diff --git a/.gitignore b/.gitignore index bc60297aa..91dbe985b 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,7 @@ awscpu .coverage -bin/ +# bin/ build/ vendor diff --git a/.gitmodules b/.gitmodules index ab3130d82..a22f89cdc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,20 +1,23 @@ [submodule "aptos-core"] - path = third-party/aptos-core + path = vendors/aptos-core url = https://github.com/movemntdev/aptos-core branch = m1 [submodule "x25519-dalek"] - path = third-party/x25519-dalek + path = vendors/x25519-dalek url = https://github.com/movemntdev/x25519-dalek [submodule "ed25519-dalek"] - path = third-party/ed25519-dalek + path = vendors/ed25519-dalek url = https://github.com/movemntdev/ed25519-dalek [submodule "ecosystem/evm-runtime"] path = ecosystem/evm-runtime url = https://github.com/movemntdev/move-evm-swap-backend [submodule "ecosystem/subnet-request-proxy"] - path = ecosystem/subnet-request-proxy + path = m1/subnet-request-proxy url = https://github.com/movemntdev/subnet-request-proxy [submodule "aptos-pre-core-v2"] - path = third-party/aptos-core-1.7 + path = vendors/aptos-core-1.7 url = https://github.com/movemntdev/aptos-core branch = testnet +[submodule "m1/third-party/sui"] + path = vendors/sui + url = https://github.com/movemntdev/sui diff --git a/canonical/.cargo/config.toml b/canonical/.cargo/config.toml new file mode 100644 index 000000000..f93b5556e --- /dev/null +++ b/canonical/.cargo/config.toml @@ -0,0 +1,33 @@ +[alias] +xclippy = [ + "clippy", + "--workspace", + "--all-targets", + "--", + "-Dwarnings", + "-Wclippy::all", + "-Aclippy::upper_case_acronyms", + "-Aclippy::enum-variant-names", + "-Aclippy::result-large-err", + "-Aclippy::mutable-key-type", +] + +[build] +rustflags = ["--cfg", "tokio_unstable", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes"] + +# TODO(grao): Figure out whether we should enable other cpu features, and whether we should use a different way to configure them rather than list every single one here. +[target.x86_64-unknown-linux-gnu] +rustflags = ["--cfg", "tokio_unstable", "-C", "link-arg=-fuse-ld=lld", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes", "-C", "target-feature=+sse4.2"] + +# 64 bit MSVC +[target.x86_64-pc-windows-msvc] +rustflags = [ + "--cfg", + "tokio_unstable", + "-C", + "force-frame-pointers=yes", + "-C", + "force-unwind-tables=yes", + "-C", + "link-arg=/STACK:8000000" # Set stack to 8 MB +] diff --git a/canonical/.gitignore b/canonical/.gitignore new file mode 100644 index 000000000..1de565933 --- /dev/null +++ b/canonical/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/canonical/Cargo.lock b/canonical/Cargo.lock new file mode 100644 index 000000000..83fd646a5 --- /dev/null +++ b/canonical/Cargo.lock @@ -0,0 +1,11695 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom 0.2.10", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy 0.7.25", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anemo" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/anemo.git?rev=1169850e6af127397068cd86764c29b1d49dbe35#1169850e6af127397068cd86764c29b1d49dbe35" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "bytes", + "ed25519", + "futures 0.3.28", + "hex", + "http", + "matchit 0.5.0", + "pin-project-lite", + "pkcs8 0.9.0", + "quinn", + "quinn-proto", + "rand 0.8.5", + "rcgen 0.9.3", + "ring 0.16.20", + "rustls", + "rustls-webpki", + "serde 1.0.190", + "serde_json", + "socket2 0.5.5", + "tap", + "thiserror", + "tokio", + "tokio-util 0.7.10", + "tower", + "tracing", + "x509-parser 0.14.0", +] + +[[package]] +name = "anemo-build" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/anemo.git?rev=1169850e6af127397068cd86764c29b1d49dbe35#1169850e6af127397068cd86764c29b1d49dbe35" +dependencies = [ + "prettyplease 0.1.25", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "anemo-tower" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/anemo.git?rev=1169850e6af127397068cd86764c29b1d49dbe35#1169850e6af127397068cd86764c29b1d49dbe35" +dependencies = [ + "anemo", + "bytes", + "dashmap", + "futures 0.3.28", + "governor", + "nonzero_ext", + "pin-project-lite", + "tokio", + "tower", + "tracing", + "uuid", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +dependencies = [ + "backtrace", +] + +[[package]] +name = "aptos-aggregator" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-crypto", + "aptos-state-view", + "aptos-types", + "bcs 0.1.4", + "better_any", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-table-extension", + "once_cell", + "smallvec", +] + +[[package]] +name = "aptos-bitvec" +version = "0.1.0-canonical-aptos" +dependencies = [ + "serde 1.0.190", + "serde_bytes", +] + +[[package]] +name = "aptos-block-executor" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-aggregator", + "aptos-infallible", + "aptos-logger", + "aptos-metrics-core", + "aptos-mvhashmap", + "aptos-state-view", + "aptos-types", + "aptos-vm-logging", + "arc-swap", + "bcs 0.1.4", + "crossbeam", + "dashmap", + "move-binary-format 0.0.3-canonical-aptos", + "num_cpus", + "once_cell", + "parking_lot 0.12.1", + "rayon", +] + +[[package]] +name = "aptos-block-partitioner" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-crypto", + "aptos-logger", + "aptos-metrics-core", + "aptos-types", + "bcs 0.1.4", + "clap 4.4.7", + "dashmap", + "itertools 0.10.5", + "move-core-types 0.0.4-canonical-aptos", + "once_cell", + "rand 0.7.3", + "rayon", +] + +[[package]] +name = "aptos-crypto" +version = "0.0.3-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-crypto-derive", + "ark-ec", + "ark-ff", + "ark-std", + "bcs 0.1.4", + "blst", + "bytes", + "curve25519-dalek", + "digest 0.9.0", + "ed25519-dalek", + "hex", + "hkdf 0.10.0", + "libsecp256k1", + "more-asserts", + "once_cell", + "proptest", + "proptest-derive", + "rand 0.7.3", + "rand_core 0.5.1", + "ring 0.16.20", + "serde 1.0.190", + "serde-name 0.1.2", + "serde_bytes", + "sha2 0.10.8", + "sha2 0.9.9", + "static_assertions", + "thiserror", + "tiny-keccak", + "x25519-dalek", +] + +[[package]] +name = "aptos-crypto-derive" +version = "0.0.3-canonical-aptos" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "aptos-framework" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-aggregator", + "aptos-crypto", + "aptos-gas-algebra-ext", + "aptos-move-stdlib", + "aptos-sdk-builder", + "aptos-state-view", + "aptos-types", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", + "base64 0.13.1", + "bcs 0.1.4", + "better_any", + "blake2-rfc", + "blst", + "clap 4.4.7", + "codespan-reporting", + "curve25519-dalek", + "flate2", + "hex", + "include_dir 0.7.3", + "itertools 0.10.5", + "libsecp256k1", + "log", + "move-binary-format 0.0.3-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-docgen 0.1.0-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "move-package 0.1.0-canonical-aptos", + "move-prover 0.1.0-canonical-aptos", + "move-prover-boogie-backend 0.1.0-canonical-aptos", + "move-stackless-bytecode 0.1.0-canonical-aptos", + "move-table-extension", + "move-vm-runtime 0.1.0-canonical-aptos", + "move-vm-types 0.1.0-canonical-aptos", + "num-traits 0.2.17", + "once_cell", + "rand 0.7.3", + "rand_core 0.5.1", + "rayon", + "ripemd", + "serde 1.0.190", + "serde_bytes", + "serde_json", + "serde_yaml 0.8.26", + "sha2 0.10.8", + "sha2 0.9.9", + "sha3 0.9.1", + "siphasher", + "smallvec", + "tempfile", + "thiserror", + "tiny-keccak", +] + +[[package]] +name = "aptos-gas" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-framework", + "aptos-gas-algebra-ext", + "aptos-global-constants", + "aptos-logger", + "aptos-move-stdlib", + "aptos-package-builder", + "aptos-types", + "aptos-vm-types", + "bcs 0.1.4", + "clap 4.4.7", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "move-table-extension", + "move-vm-types 0.1.0-canonical-aptos", +] + +[[package]] +name = "aptos-gas-algebra-ext" +version = "0.0.1-canonical-aptos" +dependencies = [ + "move-core-types 0.0.4-canonical-aptos", +] + +[[package]] +name = "aptos-global-constants" +version = "0.1.0-canonical-aptos" + +[[package]] +name = "aptos-infallible" +version = "0.1.0-canonical-aptos" + +[[package]] +name = "aptos-log-derive" +version = "0.1.0-canonical-aptos" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "aptos-logger" +version = "0.1.0-canonical-aptos" +dependencies = [ + "aptos-infallible", + "aptos-log-derive", + "aptos-node-identity", + "backtrace", + "chrono", + "erased-serde", + "futures 0.3.28", + "hostname", + "once_cell", + "prometheus", + "serde 1.0.190", + "serde_json", + "strum", + "strum_macros", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "aptos-memory-usage-tracker" +version = "0.1.0-canonical-aptos" +dependencies = [ + "aptos-gas", + "aptos-types", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-vm-types 0.1.0-canonical-aptos", +] + +[[package]] +name = "aptos-metrics-core" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "prometheus", +] + +[[package]] +name = "aptos-move-stdlib" +version = "0.1.1-canonical-aptos" +dependencies = [ + "anyhow", + "hex", + "log", + "move-binary-format 0.0.3-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-docgen 0.1.0-canonical-aptos", + "move-errmapgen 0.1.0-canonical-aptos", + "move-prover 0.1.0-canonical-aptos", + "move-vm-runtime 0.1.0-canonical-aptos", + "move-vm-types 0.1.0-canonical-aptos", + "sha2 0.9.9", + "sha3 0.9.1", + "smallvec", + "walkdir", +] + +[[package]] +name = "aptos-mvhashmap" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-aggregator", + "aptos-crypto", + "aptos-infallible", + "aptos-types", + "bcs 0.1.4", + "crossbeam", + "dashmap", +] + +[[package]] +name = "aptos-node-identity" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-types", + "claims", + "hostname", + "once_cell", +] + +[[package]] +name = "aptos-package-builder" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-framework", + "itertools 0.10.5", + "move-command-line-common 0.1.0-canonical-aptos", + "move-package 0.1.0-canonical-aptos", + "tempfile", +] + +[[package]] +name = "aptos-scratchpad" +version = "0.1.0-canonical-aptos" +dependencies = [ + "aptos-crypto", + "aptos-infallible", + "aptos-metrics-core", + "aptos-types", + "bitvec 1.0.1", + "itertools 0.10.5", + "once_cell", + "rayon", + "thiserror", +] + +[[package]] +name = "aptos-sdk-builder" +version = "0.2.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-types", + "bcs 0.1.4", + "clap 4.4.7", + "heck 0.3.3", + "move-core-types 0.0.4-canonical-aptos", + "once_cell", + "regex", + "serde-generate", + "serde-reflection 0.3.5", + "serde_yaml 0.8.26", + "textwrap 0.15.2", +] + +[[package]] +name = "aptos-secure-net" +version = "0.1.0-canonical-aptos" +dependencies = [ + "aptos-logger", + "aptos-metrics-core", + "once_cell", + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "aptos-speculative-state-helper" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-infallible", + "crossbeam", + "once_cell", + "rayon", +] + +[[package]] +name = "aptos-state-view" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-crypto", + "aptos-types", + "bcs 0.1.4", + "serde 1.0.190", + "serde_bytes", + "serde_json", +] + +[[package]] +name = "aptos-storage-interface" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-crypto", + "aptos-logger", + "aptos-metrics-core", + "aptos-scratchpad", + "aptos-secure-net", + "aptos-state-view", + "aptos-types", + "aptos-vm", + "arr_macro", + "bcs 0.1.4", + "crossbeam-channel", + "dashmap", + "itertools 0.10.5", + "move-core-types 0.0.4-canonical-aptos", + "once_cell", + "parking_lot 0.12.1", + "rayon", + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "aptos-types" +version = "0.0.3-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-bitvec", + "aptos-crypto", + "aptos-crypto-derive", + "arr_macro", + "bcs 0.1.4", + "chrono", + "derivative", + "hex", + "itertools 0.10.5", + "move-core-types 0.0.4-canonical-aptos", + "move-table-extension", + "num-derive", + "num-traits 0.2.17", + "once_cell", + "rand 0.7.3", + "rayon", + "serde 1.0.190", + "serde_bytes", + "serde_json", + "serde_yaml 0.8.26", + "thiserror", + "tiny-keccak", +] + +[[package]] +name = "aptos-utils" +version = "0.1.0-canonical-aptos" + +[[package]] +name = "aptos-vm" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-aggregator", + "aptos-block-executor", + "aptos-block-partitioner", + "aptos-crypto", + "aptos-crypto-derive", + "aptos-framework", + "aptos-gas", + "aptos-infallible", + "aptos-logger", + "aptos-memory-usage-tracker", + "aptos-metrics-core", + "aptos-move-stdlib", + "aptos-mvhashmap", + "aptos-state-view", + "aptos-types", + "aptos-utils", + "aptos-vm-logging", + "aptos-vm-types", + "bcs 0.1.4", + "dashmap", + "fail 0.5.1", + "futures 0.3.28", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-utils 0.1.0-canonical-aptos", + "move-bytecode-verifier 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-table-extension", + "move-vm-runtime 0.1.0-canonical-aptos", + "move-vm-test-utils 0.1.0-canonical-aptos", + "move-vm-types 0.1.0-canonical-aptos", + "num_cpus", + "once_cell", + "ouroboros 0.15.6", + "rand 0.7.3", + "rayon", + "serde 1.0.190", + "serde_json", + "smallvec", + "tracing", +] + +[[package]] +name = "aptos-vm-logging" +version = "0.1.0-canonical-aptos" +dependencies = [ + "aptos-crypto", + "aptos-logger", + "aptos-metrics-core", + "aptos-speculative-state-helper", + "aptos-state-view", + "aptos-types", + "arc-swap", + "once_cell", + "serde 1.0.190", +] + +[[package]] +name = "aptos-vm-types" +version = "0.0.1-canonical-aptos" +dependencies = [ + "anyhow", + "aptos-aggregator", + "aptos-state-view", + "aptos-types", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", +] + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-crypto-primitives" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-relations", + "ark-serialize", + "ark-snark", + "ark-std", + "blake2", + "derivative", + "digest 0.10.7", + "sha2 0.10.8", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits 0.2.17", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits 0.2.17", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits 0.2.17", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ark-groth16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" +dependencies = [ + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-relations" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" +dependencies = [ + "ark-ff", + "ark-std", + "tracing", +] + +[[package]] +name = "ark-secp256r1" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3975a01b0a6e3eae0f72ec7ca8598a6620fc72fa5981f6f5cca33b7cd788f633" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ark-snark" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" +dependencies = [ + "ark-ff", + "ark-relations", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits 0.2.17", + "rand 0.8.5", +] + +[[package]] +name = "arr_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a105bfda48707cf19220129e78fca01e9639433ffaef4163546ed8fb04120a5" +dependencies = [ + "arr_macro_impl", + "proc-macro-hack", +] + +[[package]] +name = "arr_macro_impl" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0609c78bd572f4edc74310dfb63a01f5609d53fa8b4dd7c4d98aef3b3e8d72d1" +dependencies = [ + "proc-macro-hack", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits 0.2.17", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-compression" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "async-task" +version = "4.3.0" +source = "git+https://github.com/mystenmark/async-task?rev=4e45b26e11126b191701b9b2ce5e2346b8d7682f#4e45b26e11126b191701b9b2ce5e2346b8d7682f" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "atomic_float" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62af46d040ba9df09edc6528dae9d8e49f5f3e82f55b7d2ec31a733c38dbc49d" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "auto_ops" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "autotools" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8da1805e028a172334c3b680f93e71126f2327622faef2ec3d893c0a4ad77" +dependencies = [ + "cc", +] + +[[package]] +name = "avalanche-types" +version = "0.0.398" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94736aaa736be8376620b7dd3714d4c65a6d8740457e76277dd6ad93d19f7e64" +dependencies = [ + "async-trait", + "base64 0.21.5", + "bech32", + "blst", + "bs58 0.5.0", + "bytes", + "cert-manager", + "chrono", + "cmp-manager", + "ecdsa 0.16.8", + "ethers-core", + "futures 0.3.28", + "hex", + "hmac 0.12.1", + "http", + "hyper", + "jsonrpc-core", + "k256 0.13.1", + "lazy_static 1.4.0", + "log", + "num-derive", + "num-traits 0.2.17", + "prefix-manager", + "primitive-types 0.12.2", + "prost 0.11.9", + "protoc-gen-prost", + "protoc-gen-tonic", + "rand 0.8.5", + "ring 0.16.20", + "ripemd", + "rust-embed", + "semver", + "serde 1.0.190", + "serde_json", + "serde_with 3.4.0", + "serde_yaml 0.9.27", + "sha2 0.10.8", + "sha3 0.10.8", + "spki 0.7.2", + "strum", + "thiserror", + "tokio", + "tokio-stream", + "tonic 0.9.2", + "tonic-health 0.9.2", + "tonic-reflection", + "tower-service", + "url 2.4.1", + "zerocopy 0.6.5", + "zeroize", +] + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "base64 0.21.5", + "bitflags 1.3.2", + "bytes", + "futures-util", + "headers", + "http", + "http-body", + "hyper", + "itoa", + "matchit 0.7.3", + "memchr", + "mime", + "percent-encoding 2.3.0", + "pin-project-lite", + "rustversion", + "serde 1.0.190", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper", + "tokio", + "tokio-tungstenite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-server" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447f28c85900215cc1bea282f32d4a2f22d55c5a300afdfbc661c8d6a632e063" +dependencies = [ + "arc-swap", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "futures-core", + "getrandom 0.2.10", + "instant", + "pin-project-lite", + "rand 0.8.5", + "tokio", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64-url" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c5b0a88aa36e9f095ee2e2b13fb8c5e4313e022783aedacc123328c0084916d" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bcs" +version = "0.1.4" +source = "git+https://github.com/aptos-labs/bcs.git?rev=d31fab9d81748e2594be5cd5cdf845786a30562d#d31fab9d81748e2594be5cd5cdf845786a30562d" +dependencies = [ + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "bcs" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b6598a2f5d564fb7855dc6b06fd1c38cff5a72bd8b863a4d021938497b440a" +dependencies = [ + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "better_any" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b359aebd937c17c725e19efcb661200883f04c49c53e7132224dac26da39d4a0" +dependencies = [ + "better_typeid_derive", +] + +[[package]] +name = "better_typeid_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3deeecb812ca5300b7d3f66f730cc2ebd3511c3d36c691dd79c165d5b19a26e3" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static 1.4.0", + "lazycell", + "peeking_take_while", + "prettyplease 0.2.15", + "proc-macro2 1.0.69", + "quote 1.0.33", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.39", +] + +[[package]] +name = "bip32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +dependencies = [ + "bs58 0.4.0", + "hmac 0.12.1", + "k256 0.11.6", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitcoin-private" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" + +[[package]] +name = "bitcoin_hashes" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" +dependencies = [ + "bitcoin-private", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty 1.1.0", + "radium 0.6.2", + "tap", + "wyz 0.2.0", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty 2.0.0", + "radium 0.7.0", + "tap", + "wyz 0.5.1", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq 0.1.5", +] + +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "cc", + "cfg-if", + "constant_time_eq 0.3.0", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding 0.2.1", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2 0.9.9", +] + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "sha2 0.10.8", + "tinyvec", +] + +[[package]] +name = "bstr" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" +dependencies = [ + "memchr", + "serde 1.0.190", +] + +[[package]] +name = "bulletproofs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40e698f1df446cc6246afd823afbe2d121134d089c9102c1dd26d1264991ba32" +dependencies = [ + "byteorder", + "clear_on_drop", + "curve25519-dalek-ng", + "digest 0.9.0", + "merlin", + "rand 0.8.5", + "rand_core 0.6.4", + "serde 1.0.190", + "serde_derive", + "sha3 0.9.1", + "subtle-ng", + "thiserror", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytecount" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" + +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "bytes-varint" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c1820c7c366b9d26c47143e1604454105a59969aade54e4f695d96acc8332f" +dependencies = [ + "bytes", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" + +[[package]] +name = "canonical-block-executor" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-channel", + "avalanche-types", + "base64 0.21.5", + "bcs 0.1.6", + "bytes", + "chrono", + "derivative", + "dirs 5.0.1", + "env_logger", + "futures 0.3.28", + "hex", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "log", + "movement-sdk", + "rand 0.8.5", + "serde 1.0.190", + "serde_json", + "serde_with 2.3.3", + "sui-adapter-latest", + "sui-core", + "sui-types", + "tokio", + "tonic 0.8.3", +] + +[[package]] +name = "canonical-move-natives" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-channel", + "avalanche-types", + "base64 0.21.5", + "bcs 0.1.6", + "bytes", + "chrono", + "derivative", + "dirs 5.0.1", + "env_logger", + "futures 0.3.28", + "hex", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "log", + "movement-sdk", + "rand 0.8.5", + "serde 1.0.190", + "serde_json", + "serde_with 2.3.3", + "sui-adapter-latest", + "sui-types", + "tokio", + "tonic 0.8.3", +] + +[[package]] +name = "canonical-move-resolver" +version = "0.1.0" +dependencies = [ + "anyhow", + "aptos-storage-interface", + "async-channel", + "avalanche-types", + "base64 0.21.5", + "bcs 0.1.6", + "bytes", + "chrono", + "derivative", + "dirs 5.0.1", + "env_logger", + "futures 0.3.28", + "hex", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "log", + "movement-sdk", + "rand 0.8.5", + "serde 1.0.190", + "serde_json", + "serde_with 2.3.3", + "sui-adapter-latest", + "sui-types", + "tokio", + "tonic 0.8.3", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cert-manager" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "166da6fda67aa44381158b8ad9c3b28d842951791c431ce61333e62cb9b05d5b" +dependencies = [ + "log", + "rand 0.8.5", + "random-manager", + "rcgen 0.10.0", + "rsa 0.9.3", + "rustls", + "rustls-pemfile", + "x509-parser 0.15.1", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits 0.2.17", + "serde 1.0.190", + "wasm-bindgen", + "windows-targets 0.48.5", +] + +[[package]] +name = "chrono-tz" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e23185c0e21df6ed832a12e2bda87c7d1def6842881fb634a8511ced741b0d76" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "claims" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6995bbe186456c36307f8ea36be3eefe42f49d106896414e18efc4fb2f846b5" +dependencies = [ + "autocfg", +] + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.10.0", + "terminal_size", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "clear_on_drop" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" +dependencies = [ + "cc", +] + +[[package]] +name = "cmp-manager" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f5e2b424191b35b798b06e6c67fa5a5440a098925d931d7e91511d7d8fe275" + +[[package]] +name = "codespan" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" +dependencies = [ + "codespan-reporting", + "serde 1.0.190", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "serde 1.0.190", + "termcolor", + "unicode-width", +] + +[[package]] +name = "collectable" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08abddbaad209601e53c7dd4308d8c04c06f17bb7df006434e586a22b83be45a" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "colored" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +dependencies = [ + "is-terminal", + "lazy_static 1.4.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "concurrent-queue" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "config" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369" +dependencies = [ + "lazy_static 1.4.0", + "nom 5.1.3", + "rust-ini", + "serde 1.0.190", + "serde-hjson", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static 1.4.0", + "libc", + "unicode-width", + "windows-sys 0.45.0", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +dependencies = [ + "cfg-if", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "libc", + "mio", + "parking_lot 0.12.1", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +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 1.0.190", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[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-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "serde 1.0.190", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core 0.20.3", + "darling_macro 0.20.3", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.69", + "quote 1.0.33", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.69", + "quote 1.0.33", + "strsim 0.10.0", + "syn 2.0.39", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core 0.20.3", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "data-encoding-macro" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468 0.6.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits 0.2.17", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", + "serde 1.0.190", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling 0.14.4", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2 1.0.69", + "quote 1.0.33", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "deunicode" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6" + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + +[[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", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der 0.7.8", + "digest 0.10.7", + "elliptic-curve 0.13.6", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "pkcs8 0.9.0", + "serde 1.0.190", + "signature 1.6.4", + "zeroize", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "serde 1.0.190", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde 1.0.190", + "serde_bytes", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.3", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[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 = "enum-compat-util" +version = "0.1.0-canonical-sui" +dependencies = [ + "serde_yaml 0.8.26", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e" +dependencies = [ + "once_cell", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "erasable" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f11890ce181d47a64e5d1eb4b6caba0e7bae911a356723740d058a5d0340b7d" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde 1.0.190", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "impl-rlp", + "impl-serde 0.4.0", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "impl-rlp", + "impl-serde 0.4.0", + "primitive-types 0.12.2", + "scale-info", + "uint", +] + +[[package]] +name = "ethers-core" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da5fa198af0d3be20c19192df2bd9590b92ce09a8421e793bec8851270f1b05" +dependencies = [ + "arrayvec 0.7.4", + "bytes", + "chrono", + "elliptic-curve 0.13.6", + "ethabi", + "generic-array", + "hex", + "k256 0.13.1", + "num_enum", + "open-fastrlp", + "rand 0.8.5", + "rlp", + "serde 1.0.190", + "serde_json", + "strum", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid 0.2.4", +] + +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fail" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be3c61c59fdc91f5dbc3ea31ee8623122ce80057058be560654c5d410d181a6" +dependencies = [ + "lazy_static 1.4.0", + "log", + "rand 0.7.3", +] + +[[package]] +name = "fail" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5e43d0f78a42ad591453aedb1d7ae631ce7ee445c7643691055a9ed8d3b01c" +dependencies = [ + "log", + "once_cell", + "rand 0.8.5", +] + +[[package]] +name = "fastcrypto" +version = "0.1.7" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=517ec93ad2eba1807c9508f14953814a33523edc#517ec93ad2eba1807c9508f14953814a33523edc" +dependencies = [ + "aes", + "aes-gcm", + "ark-ec", + "ark-ff", + "ark-secp256r1", + "ark-serialize", + "auto_ops", + "base64ct", + "bincode", + "blake2", + "blake3", + "blst", + "bs58 0.4.0", + "bulletproofs", + "cbc", + "ctr", + "curve25519-dalek-ng", + "derive_more", + "digest 0.10.7", + "ecdsa 0.16.8", + "ed25519-consensus", + "elliptic-curve 0.13.6", + "eyre", + "fastcrypto-derive", + "generic-array", + "hex", + "hkdf 0.12.3", + "lazy_static 1.4.0", + "merlin", + "once_cell", + "p256", + "rand 0.8.5", + "readonly", + "rfc6979 0.4.0", + "rsa 0.8.2", + "schemars", + "secp256k1", + "serde 1.0.190", + "serde_bytes", + "serde_json", + "serde_with 2.3.3", + "sha2 0.10.8", + "sha3 0.10.8", + "signature 2.1.0", + "static_assertions", + "thiserror", + "tokio", + "typenum", + "zeroize", +] + +[[package]] +name = "fastcrypto-derive" +version = "0.1.3" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=517ec93ad2eba1807c9508f14953814a33523edc#517ec93ad2eba1807c9508f14953814a33523edc" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "fastcrypto-tbls" +version = "0.1.0" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=517ec93ad2eba1807c9508f14953814a33523edc#517ec93ad2eba1807c9508f14953814a33523edc" +dependencies = [ + "bcs 0.1.6", + "bincode", + "digest 0.10.7", + "fastcrypto", + "fastcrypto-derive", + "hex", + "itertools 0.10.5", + "rand 0.8.5", + "serde 1.0.190", + "sha3 0.10.8", + "tap", + "tracing", + "typenum", + "zeroize", +] + +[[package]] +name = "fastcrypto-zkp" +version = "0.1.2" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=517ec93ad2eba1807c9508f14953814a33523edc#517ec93ad2eba1807c9508f14953814a33523edc" +dependencies = [ + "ark-bls12-381", + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-groth16", + "ark-relations", + "ark-serialize", + "ark-snark", + "bcs 0.1.6", + "blst", + "byte-slice-cast", + "derive_more", + "fastcrypto", + "im", + "num-bigint", + "once_cell", + "poseidon-ark", + "regex", + "reqwest", + "rustls-webpki", + "schemars", + "serde 1.0.190", + "serde_json", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fdlimit" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" +dependencies = [ + "libc", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[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", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits 0.2.17", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding 2.3.0", +] + +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde 1.0.190", + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gettid" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b20f40277dfb8a9dec7e2e945f6d8ff711e733c8f2a2c9b257562764b4c60d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "git-version" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13ad01ffa8221f7fe8b936d6ffb2a3e7ad428885a04fad51866a5f33eafda57c" +dependencies = [ + "git-version-macro", +] + +[[package]] +name = "git-version-macro" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84488ccbdb24ad6f56dc1863b4a8154a7856cd3c6c7610401634fab3cb588dae" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[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.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "governor" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "821239e5672ff23e2a7060901fa622950bbd80b649cdaadd78d1c1767ed14eb4" +dependencies = [ + "cfg-if", + "dashmap", + "futures 0.3.28", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot 0.12.1", + "quanta", + "rand 0.8.5", + "smallvec", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util 0.7.10", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.6", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + +[[package]] +name = "hdrhistogram" +version = "7.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +dependencies = [ + "base64 0.13.1", + "byteorder", + "crossbeam-channel", + "flate2", + "nom 7.1.3", + "num-traits 0.2.17", +] + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.5", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[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.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" +dependencies = [ + "digest 0.9.0", + "hmac 0.10.1", +] + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.1", + "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", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "hmac-sha512" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e806677ce663d0a199541030c816847b36e8dc095f70dae4a4f4ad63da5383" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[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.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static 1.4.0", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec 2.3.1", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec 3.6.5", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "include_dir" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b56e147e6187d61e9d0f039f10e070d0c0a887e24fe0bb9ca3f29bfde62cab" +dependencies = [ + "glob", + "include_dir_impl", + "proc-macro-hack", +] + +[[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", +] + +[[package]] +name = "include_dir_impl" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0c890c85da4bab7bce4204c707396bbd3c6c8a681716a51c8814cfc2b682df" +dependencies = [ + "anyhow", + "proc-macro-hack", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde 1.0.190", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", + "serde 1.0.190", +] + +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding 0.3.3", + "generic-array", +] + +[[package]] +name = "insta" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" +dependencies = [ + "console", + "lazy_static 1.4.0", + "linked-hash-map", + "pest", + "pest_derive", + "serde 1.0.190", + "similar", + "yaml-rust", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "internment" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab388864246d58a276e60e7569a833d9cc4cd75c66e5ca77c177dad38e59996" +dependencies = [ + "ahash 0.7.7", + "dashmap", + "hashbrown 0.12.3", + "once_cell", + "parking_lot 0.12.1", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "iri-string" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi 0.3.3", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json_to_table" +version = "0.6.0" +source = "git+https://github.com/zhiburt/tabled/?rev=e449317a1c02eb6b29e409ad6617e5d9eb7b3bd4#e449317a1c02eb6b29e409ad6617e5d9eb7b3bd4" +dependencies = [ + "serde_json", + "tabled", +] + +[[package]] +name = "jsonrpc-client-transports" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a" +dependencies = [ + "derive_more", + "futures 0.3.28", + "jsonrpc-core", + "jsonrpc-pubsub", + "log", + "serde 1.0.190", + "serde_json", + "url 1.7.2", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures 0.3.28", + "futures-executor", + "futures-util", + "log", + "serde 1.0.190", + "serde_derive", + "serde_json", +] + +[[package]] +name = "jsonrpc-core-client" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0" +dependencies = [ + "futures 0.3.28", + "jsonrpc-client-transports", +] + +[[package]] +name = "jsonrpc-derive" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" +dependencies = [ + "proc-macro-crate 0.1.5", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "jsonrpc-pubsub" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011" +dependencies = [ + "futures 0.3.28", + "jsonrpc-core", + "lazy_static 1.4.0", + "log", + "parking_lot 0.11.2", + "rand 0.7.3", + "serde 1.0.190", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", + "sha3 0.10.8", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa 0.16.8", + "elliptic-curve 0.13.6", + "once_cell", + "sha2 0.10.8", + "signature 2.1.0", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec 0.5.2", + "bitflags 1.3.2", + "cfg-if", + "ryu", + "static_assertions", +] + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libm" +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.1", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "lz4-sys", + "zstd-sys", +] + +[[package]] +name = "libsecp256k1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64 0.13.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.8.5", + "serde 1.0.190", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "lz4-sys" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "mach2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +dependencies = [ + "libc", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "match_opt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "405ba1524a1e6ae755334d6966380c60ec40157e0155f9032dd3c294b6384da9" + +[[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 = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minibytes" +version = "0.1.0" +source = "git+https://github.com/MystenLabs/mysticeti?rev=318d61d27f47d257d99a86983d835e9e9756bc59#318d61d27f47d257d99a86983d835e9e9756bc59" +dependencies = [ + "memmap2", + "serde 1.0.190", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "mockall" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static 1.4.0", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +dependencies = [ + "cfg-if", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "more-asserts" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" + +[[package]] +name = "move-abigen" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "heck 0.3.3", + "log", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-verifier 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "serde 1.0.190", +] + +[[package]] +name = "move-abigen" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "heck 0.3.3", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-verifier 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-model 0.1.0-canonical-sui", + "serde 1.0.190", +] + +[[package]] +name = "move-abstract-stack" +version = "0.0.1-canonical-sui" + +[[package]] +name = "move-binary-format" +version = "0.0.3-canonical-aptos" +dependencies = [ + "anyhow", + "backtrace", + "indexmap 1.9.3", + "move-core-types 0.0.4-canonical-aptos", + "once_cell", + "ref-cast", + "serde 1.0.190", + "variant_count", +] + +[[package]] +name = "move-binary-format" +version = "0.0.3-canonical-sui" +dependencies = [ + "anyhow", + "enum-compat-util", + "move-core-types 0.0.4-canonical-sui", + "move-proc-macros", + "ref-cast", + "serde 1.0.190", + "variant_count", +] + +[[package]] +name = "move-borrow-graph" +version = "0.0.1-canonical-aptos" + +[[package]] +name = "move-borrow-graph" +version = "0.0.1-canonical-sui" + +[[package]] +name = "move-bytecode-source-map" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "move-binary-format 0.0.3-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", + "move-symbol-pool 0.1.0-canonical-aptos", + "serde 1.0.190", +] + +[[package]] +name = "move-bytecode-source-map" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "move-binary-format 0.0.3-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "serde 1.0.190", +] + +[[package]] +name = "move-bytecode-utils" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "petgraph 0.5.1", + "serde-reflection 0.3.6", +] + +[[package]] +name = "move-bytecode-utils" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "petgraph 0.5.1", + "serde-reflection 0.3.6", +] + +[[package]] +name = "move-bytecode-verifier" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "fail 0.4.0", + "move-binary-format 0.0.3-canonical-aptos", + "move-borrow-graph 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "petgraph 0.5.1", + "typed-arena", +] + +[[package]] +name = "move-bytecode-verifier" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-abstract-stack", + "move-binary-format 0.0.3-canonical-sui", + "move-borrow-graph 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "petgraph 0.5.1", +] + +[[package]] +name = "move-bytecode-verifier-v0" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-abstract-stack", + "move-binary-format 0.0.3-canonical-sui", + "move-borrow-graph 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "petgraph 0.5.1", +] + +[[package]] +name = "move-bytecode-verifier-v1" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-abstract-stack", + "move-binary-format 0.0.3-canonical-sui", + "move-borrow-graph 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "petgraph 0.5.1", +] + +[[package]] +name = "move-command-line-common" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "difference", + "dirs-next", + "hex", + "move-core-types 0.0.4-canonical-aptos", + "num-bigint", + "once_cell", + "serde 1.0.190", + "sha2 0.9.9", + "walkdir", +] + +[[package]] +name = "move-command-line-common" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "difference", + "dirs-next", + "hex", + "move-core-types 0.0.4-canonical-sui", + "num-bigint", + "once_cell", + "serde 1.0.190", + "sha2 0.9.9", + "walkdir", +] + +[[package]] +name = "move-compiler" +version = "0.0.1-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "clap 4.4.7", + "codespan-reporting", + "difference", + "hex", + "move-binary-format 0.0.3-canonical-aptos", + "move-borrow-graph 0.0.1-canonical-aptos", + "move-bytecode-source-map 0.1.0-canonical-aptos", + "move-bytecode-verifier 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-ir-to-bytecode 0.1.0-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", + "move-symbol-pool 0.1.0-canonical-aptos", + "num-bigint", + "once_cell", + "petgraph 0.5.1", + "regex", + "sha3 0.9.1", + "tempfile", + "walkdir", +] + +[[package]] +name = "move-compiler" +version = "0.0.1-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "clap 4.4.7", + "codespan-reporting", + "hex", + "move-binary-format 0.0.3-canonical-sui", + "move-borrow-graph 0.0.1-canonical-sui", + "move-bytecode-source-map 0.1.0-canonical-sui", + "move-bytecode-verifier 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-ir-to-bytecode 0.1.0-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "once_cell", + "petgraph 0.5.1", + "regex", + "serde 1.0.190", + "tempfile", +] + +[[package]] +name = "move-core-types" +version = "0.0.4-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "ethnum", + "hex", + "num", + "once_cell", + "primitive-types 0.10.1", + "rand 0.8.5", + "ref-cast", + "serde 1.0.190", + "serde_bytes", + "uint", +] + +[[package]] +name = "move-core-types" +version = "0.0.4-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "enum-compat-util", + "ethnum", + "hex", + "move-proc-macros", + "num", + "once_cell", + "primitive-types 0.10.1", + "rand 0.8.5", + "ref-cast", + "serde 1.0.190", + "serde_bytes", + "uint", +] + +[[package]] +name = "move-coverage" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "clap 4.4.7", + "codespan", + "colored", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-source-map 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", + "once_cell", + "petgraph 0.5.1", + "serde 1.0.190", +] + +[[package]] +name = "move-coverage" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "clap 4.4.7", + "codespan", + "colored", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-source-map 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "petgraph 0.5.1", + "serde 1.0.190", +] + +[[package]] +name = "move-disassembler" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "clap 4.4.7", + "colored", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-source-map 0.1.0-canonical-aptos", + "move-bytecode-verifier 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-coverage 0.1.0-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", +] + +[[package]] +name = "move-disassembler" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "clap 4.4.7", + "colored", + "hex", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-source-map 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-compiler 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-coverage 0.1.0-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", +] + +[[package]] +name = "move-docgen" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "itertools 0.10.5", + "log", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "num", + "once_cell", + "regex", + "serde 1.0.190", +] + +[[package]] +name = "move-docgen" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "itertools 0.10.5", + "log", + "move-compiler 0.0.1-canonical-sui", + "move-model 0.1.0-canonical-sui", + "num", + "once_cell", + "regex", + "serde 1.0.190", +] + +[[package]] +name = "move-errmapgen" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "log", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "serde 1.0.190", +] + +[[package]] +name = "move-errmapgen" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-model 0.1.0-canonical-sui", + "serde 1.0.190", +] + +[[package]] +name = "move-ir-to-bytecode" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "codespan-reporting", + "log", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-source-map 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-ir-to-bytecode-syntax 0.1.0-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", + "move-symbol-pool 0.1.0-canonical-aptos", + "ouroboros 0.9.5", + "thiserror", +] + +[[package]] +name = "move-ir-to-bytecode" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "codespan-reporting", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-source-map 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-ir-to-bytecode-syntax 0.1.0-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "ouroboros 0.17.2", +] + +[[package]] +name = "move-ir-to-bytecode-syntax" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "hex", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", + "move-symbol-pool 0.1.0-canonical-aptos", +] + +[[package]] +name = "move-ir-to-bytecode-syntax" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "hex", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", +] + +[[package]] +name = "move-ir-types" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "hex", + "move-command-line-common 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-symbol-pool 0.1.0-canonical-aptos", + "once_cell", + "serde 1.0.190", +] + +[[package]] +name = "move-ir-types" +version = "0.1.0-canonical-sui" +dependencies = [ + "hex", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "once_cell", + "serde 1.0.190", +] + +[[package]] +name = "move-model" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "internment", + "itertools 0.10.5", + "log", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-source-map 0.1.0-canonical-aptos", + "move-bytecode-verifier 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-disassembler 0.1.0-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", + "move-symbol-pool 0.1.0-canonical-aptos", + "num", + "once_cell", + "regex", + "serde 1.0.190", + "trace", +] + +[[package]] +name = "move-model" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "internment", + "itertools 0.10.5", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-source-map 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-compiler 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-disassembler 0.1.0-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "num", + "once_cell", + "regex", + "serde 1.0.190", +] + +[[package]] +name = "move-package" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "clap 4.4.7", + "colored", + "dirs-next", + "itertools 0.10.5", + "move-abigen 0.1.0-canonical-aptos", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-source-map 0.1.0-canonical-aptos", + "move-bytecode-utils 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-docgen 0.1.0-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "move-symbol-pool 0.1.0-canonical-aptos", + "named-lock", + "once_cell", + "petgraph 0.5.1", + "ptree", + "regex", + "reqwest", + "serde 1.0.190", + "serde_yaml 0.8.26", + "sha2 0.9.9", + "tempfile", + "toml", + "walkdir", + "whoami", +] + +[[package]] +name = "move-package" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "clap 4.4.7", + "colored", + "move-abigen 0.1.0-canonical-sui", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-source-map 0.1.0-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-compiler 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-docgen 0.1.0-canonical-sui", + "move-model 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "named-lock", + "once_cell", + "petgraph 0.5.1", + "regex", + "serde 1.0.190", + "serde_yaml 0.8.26", + "sha2 0.9.9", + "tempfile", + "toml", + "treeline", + "walkdir", + "whoami", +] + +[[package]] +name = "move-proc-macros" +version = "0.1.0-canonical-sui" +dependencies = [ + "enum-compat-util", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "move-prover" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "async-trait", + "atty", + "clap 4.4.7", + "codespan", + "codespan-reporting", + "futures 0.3.28", + "hex", + "itertools 0.10.5", + "log", + "move-abigen 0.1.0-canonical-aptos", + "move-binary-format 0.0.3-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-docgen 0.1.0-canonical-aptos", + "move-errmapgen 0.1.0-canonical-aptos", + "move-ir-types 0.1.0-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "move-prover-boogie-backend 0.1.0-canonical-aptos", + "move-stackless-bytecode 0.1.0-canonical-aptos", + "num", + "once_cell", + "pretty", + "rand 0.8.5", + "serde 1.0.190", + "serde_json", + "simplelog", + "tokio", + "toml", +] + +[[package]] +name = "move-prover" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "clap 4.4.7", + "codespan-reporting", + "itertools 0.10.5", + "log", + "move-abigen 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-compiler 0.0.1-canonical-sui", + "move-docgen 0.1.0-canonical-sui", + "move-errmapgen 0.1.0-canonical-sui", + "move-model 0.1.0-canonical-sui", + "move-prover-boogie-backend 0.1.0-canonical-sui", + "move-stackless-bytecode 0.1.0-canonical-sui", + "once_cell", + "serde 1.0.190", + "simplelog", + "toml", +] + +[[package]] +name = "move-prover-boogie-backend" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "async-trait", + "codespan", + "codespan-reporting", + "futures 0.3.28", + "itertools 0.10.5", + "log", + "move-binary-format 0.0.3-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "move-stackless-bytecode 0.1.0-canonical-aptos", + "num", + "once_cell", + "pretty", + "rand 0.8.5", + "regex", + "serde 1.0.190", + "serde_json", + "tera", + "tokio", +] + +[[package]] +name = "move-prover-boogie-backend" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "async-trait", + "codespan", + "codespan-reporting", + "futures 0.3.28", + "itertools 0.10.5", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-model 0.1.0-canonical-sui", + "move-stackless-bytecode 0.1.0-canonical-sui", + "num", + "once_cell", + "pretty", + "rand 0.8.5", + "regex", + "serde 1.0.190", + "tera", + "tokio", +] + +[[package]] +name = "move-read-write-set-types" +version = "0.0.3-canonical-sui" +dependencies = [ + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "serde 1.0.190", +] + +[[package]] +name = "move-stackless-bytecode" +version = "0.1.0-canonical-aptos" +dependencies = [ + "codespan", + "codespan-reporting", + "ethnum", + "im", + "itertools 0.10.5", + "log", + "move-binary-format 0.0.3-canonical-aptos", + "move-borrow-graph 0.0.1-canonical-aptos", + "move-bytecode-verifier 0.1.0-canonical-aptos", + "move-command-line-common 0.1.0-canonical-aptos", + "move-compiler 0.0.1-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-ir-to-bytecode 0.1.0-canonical-aptos", + "move-model 0.1.0-canonical-aptos", + "num", + "once_cell", + "paste", + "petgraph 0.5.1", + "serde 1.0.190", +] + +[[package]] +name = "move-stackless-bytecode" +version = "0.1.0-canonical-sui" +dependencies = [ + "codespan", + "codespan-reporting", + "ethnum", + "im", + "itertools 0.10.5", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-compiler 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-model 0.1.0-canonical-sui", + "move-read-write-set-types", + "num", + "paste", + "petgraph 0.5.1", + "serde 1.0.190", +] + +[[package]] +name = "move-stdlib" +version = "0.1.1-canonical-sui" +dependencies = [ + "anyhow", + "hex", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-docgen 0.1.0-canonical-sui", + "move-errmapgen 0.1.0-canonical-sui", + "move-prover 0.1.0-canonical-sui", + "move-vm-runtime 0.1.0-canonical-sui", + "move-vm-types 0.1.0-canonical-sui", + "sha2 0.9.9", + "sha3 0.9.1", + "smallvec", + "walkdir", +] + +[[package]] +name = "move-stdlib-v0" +version = "0.1.1-canonical-sui" +dependencies = [ + "anyhow", + "hex", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-docgen 0.1.0-canonical-sui", + "move-errmapgen 0.1.0-canonical-sui", + "move-prover 0.1.0-canonical-sui", + "move-vm-runtime-v0", + "move-vm-types 0.1.0-canonical-sui", + "sha2 0.9.9", + "sha3 0.9.1", + "smallvec", + "walkdir", +] + +[[package]] +name = "move-stdlib-v1" +version = "0.1.1-canonical-sui" +dependencies = [ + "anyhow", + "hex", + "log", + "move-binary-format 0.0.3-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-docgen 0.1.0-canonical-sui", + "move-errmapgen 0.1.0-canonical-sui", + "move-prover 0.1.0-canonical-sui", + "move-vm-runtime-v1", + "move-vm-types 0.1.0-canonical-sui", + "sha2 0.9.9", + "sha3 0.9.1", + "smallvec", + "walkdir", +] + +[[package]] +name = "move-symbol-pool" +version = "0.1.0-canonical-aptos" +dependencies = [ + "once_cell", + "serde 1.0.190", +] + +[[package]] +name = "move-symbol-pool" +version = "0.1.0-canonical-sui" +dependencies = [ + "once_cell", + "phf", + "serde 1.0.190", +] + +[[package]] +name = "move-table-extension" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "bcs 0.1.4", + "better_any", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-vm-runtime 0.1.0-canonical-aptos", + "move-vm-types 0.1.0-canonical-aptos", + "once_cell", + "sha3 0.9.1", + "smallvec", +] + +[[package]] +name = "move-vm-config" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-binary-format 0.0.3-canonical-sui", +] + +[[package]] +name = "move-vm-profiler" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-vm-config", + "once_cell", + "serde 1.0.190", + "serde_json", +] + +[[package]] +name = "move-vm-runtime" +version = "0.1.0-canonical-aptos" +dependencies = [ + "better_any", + "fail 0.4.0", + "move-binary-format 0.0.3-canonical-aptos", + "move-bytecode-verifier 0.1.0-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-vm-types 0.1.0-canonical-aptos", + "once_cell", + "parking_lot 0.11.2", + "sha3 0.9.1", + "tracing", +] + +[[package]] +name = "move-vm-runtime" +version = "0.1.0-canonical-sui" +dependencies = [ + "better_any", + "fail 0.4.0", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-verifier 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "move-vm-profiler", + "move-vm-types 0.1.0-canonical-sui", + "once_cell", + "parking_lot 0.11.2", + "sha3 0.9.1", + "smallvec", + "tracing", +] + +[[package]] +name = "move-vm-runtime-v0" +version = "0.1.0-canonical-sui" +dependencies = [ + "better_any", + "fail 0.4.0", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-verifier-v0", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "move-vm-profiler", + "move-vm-types 0.1.0-canonical-sui", + "once_cell", + "parking_lot 0.11.2", + "sha3 0.9.1", + "smallvec", + "tracing", +] + +[[package]] +name = "move-vm-runtime-v1" +version = "0.1.0-canonical-sui" +dependencies = [ + "better_any", + "fail 0.4.0", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-verifier-v1", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "move-vm-profiler", + "move-vm-types 0.1.0-canonical-sui", + "once_cell", + "parking_lot 0.11.2", + "sha3 0.9.1", + "smallvec", + "tracing", +] + +[[package]] +name = "move-vm-test-utils" +version = "0.1.0-canonical-aptos" +dependencies = [ + "anyhow", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "move-table-extension", + "move-vm-types 0.1.0-canonical-aptos", + "once_cell", + "serde 1.0.190", +] + +[[package]] +name = "move-vm-test-utils" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-profiler", + "move-vm-types 0.1.0-canonical-sui", + "once_cell", + "serde 1.0.190", +] + +[[package]] +name = "move-vm-types" +version = "0.1.0-canonical-aptos" +dependencies = [ + "bcs 0.1.4", + "move-binary-format 0.0.3-canonical-aptos", + "move-core-types 0.0.4-canonical-aptos", + "once_cell", + "serde 1.0.190", + "smallvec", +] + +[[package]] +name = "move-vm-types" +version = "0.1.0-canonical-sui" +dependencies = [ + "bcs 0.1.6", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-profiler", + "serde 1.0.190", + "smallvec", +] + +[[package]] +name = "movement-sdk" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "serde 1.0.190", +] + +[[package]] +name = "msim" +version = "0.1.0" +source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=1a52783d6600ecc22e15253a982f77881bd47c77#1a52783d6600ecc22e15253a982f77881bd47c77" +dependencies = [ + "ahash 0.7.7", + "async-task", + "bincode", + "bytes", + "cc", + "downcast-rs", + "erasable", + "futures 0.3.28", + "lazy_static 1.4.0", + "libc", + "msim-macros", + "naive-timer", + "pin-project-lite", + "rand 0.8.5", + "real_tokio", + "serde 1.0.190", + "socket2 0.4.10", + "tap", + "tokio-util 0.7.7", + "toml", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "msim-macros" +version = "0.1.0" +source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=1a52783d6600ecc22e15253a982f77881bd47c77#1a52783d6600ecc22e15253a982f77881bd47c77" +dependencies = [ + "darling 0.14.4", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "log", + "multibase", + "multihash", + "percent-encoding 2.3.0", + "serde 1.0.190", + "static_assertions", + "unsigned-varint", + "url 2.4.1", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "multihash-derive", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "mysten-common" +version = "0.1.0-canonical-sui" +dependencies = [ + "futures 0.3.28", + "parking_lot 0.12.1", + "tokio", + "workspace-hack", +] + +[[package]] +name = "mysten-metrics" +version = "0.7.0-canonical-sui" +dependencies = [ + "async-trait", + "axum", + "dashmap", + "futures 0.3.28", + "once_cell", + "parking_lot 0.12.1", + "prometheus", + "prometheus-closure-metric", + "scopeguard", + "tap", + "tokio", + "tracing", + "uuid", + "workspace-hack", +] + +[[package]] +name = "mysten-network" +version = "0.2.0-canonical-sui" +dependencies = [ + "anemo", + "bcs 0.1.6", + "bytes", + "eyre", + "futures 0.3.28", + "http", + "multiaddr", + "serde 1.0.190", + "snap", + "tokio", + "tokio-stream", + "tonic 0.10.2", + "tonic-health 0.10.2", + "tower", + "tower-http", + "tracing", + "workspace-hack", +] + +[[package]] +name = "mysten-util-mem" +version = "0.11.0-canonical-sui" +dependencies = [ + "cfg-if", + "ed25519-consensus", + "fastcrypto", + "fastcrypto-tbls", + "hashbrown 0.12.3", + "impl-trait-for-tuples", + "indexmap 1.9.3", + "mysten-util-mem-derive", + "once_cell", + "parking_lot 0.12.1", + "roaring", + "smallvec", + "workspace-hack", +] + +[[package]] +name = "mysten-util-mem-derive" +version = "0.1.0-canonical-sui" +dependencies = [ + "proc-macro2 1.0.69", + "syn 1.0.109", + "synstructure", + "workspace-hack", +] + +[[package]] +name = "mysticeti-core" +version = "0.1.0" +source = "git+https://github.com/MystenLabs/mysticeti?rev=318d61d27f47d257d99a86983d835e9e9756bc59#318d61d27f47d257d99a86983d835e9e9756bc59" +dependencies = [ + "async-trait", + "axum", + "bincode", + "blake2", + "crc32fast", + "digest 0.10.7", + "ed25519-consensus", + "eyre", + "futures 0.3.28", + "gettid", + "hex", + "hyper", + "libc", + "memmap2", + "minibytes", + "parking_lot 0.12.1", + "prometheus", + "rand 0.8.5", + "serde 1.0.190", + "serde_yaml 0.9.27", + "tabled", + "tempfile", + "tokio", + "tracing", + "tracing-core", + "tracing-subscriber", + "zeroize", +] + +[[package]] +name = "naive-timer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034a0ad7deebf0c2abcf2435950a6666c3c15ea9d8fad0c0f48efa8a7f843fed" + +[[package]] +name = "named-lock" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a3eb6b7c682b65d1f631ec3176829d72ab450b3aacdd3f719bf220822e59ac" +dependencies = [ + "libc", + "once_cell", + "parking_lot 0.12.1", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "narwhal-config" +version = "0.1.0-canonical-sui" +dependencies = [ + "fastcrypto", + "fastcrypto-tbls", + "match_opt", + "mysten-network", + "mysten-util-mem", + "narwhal-crypto", + "rand 0.8.5", + "serde 1.0.190", + "serde_json", + "thiserror", + "tracing", + "workspace-hack", +] + +[[package]] +name = "narwhal-crypto" +version = "0.1.0-canonical-sui" +dependencies = [ + "bcs 0.1.6", + "fastcrypto", + "fastcrypto-tbls", + "serde 1.0.190", + "shared-crypto", + "workspace-hack", +] + +[[package]] +name = "narwhal-executor" +version = "0.1.0-canonical-sui" +dependencies = [ + "async-trait", + "bcs 0.1.6", + "bincode", + "bytes", + "fastcrypto", + "futures 0.3.28", + "mockall", + "mysten-metrics", + "narwhal-config", + "narwhal-crypto", + "narwhal-network", + "narwhal-primary", + "narwhal-storage", + "narwhal-types", + "prometheus", + "serde 1.0.190", + "sui-protocol-config", + "thiserror", + "tokio", + "tonic 0.10.2", + "tracing", + "typed-store", + "workspace-hack", +] + +[[package]] +name = "narwhal-network" +version = "0.1.0-canonical-sui" +dependencies = [ + "anemo", + "anemo-tower", + "anyhow", + "async-trait", + "axum", + "axum-server", + "backoff", + "bytes", + "dashmap", + "futures 0.3.28", + "mysten-common", + "mysten-metrics", + "narwhal-crypto", + "narwhal-types", + "parking_lot 0.12.1", + "prometheus", + "quinn-proto", + "rand 0.8.5", + "sui-macros", + "tokio", + "tower", + "tracing", + "workspace-hack", +] + +[[package]] +name = "narwhal-node" +version = "0.1.0-canonical-sui" +dependencies = [ + "anemo", + "arc-swap", + "async-trait", + "axum", + "bytes", + "cfg-if", + "clap 4.4.7", + "eyre", + "fastcrypto", + "futures 0.3.28", + "mysten-metrics", + "mysten-network", + "narwhal-config", + "narwhal-crypto", + "narwhal-executor", + "narwhal-network", + "narwhal-primary", + "narwhal-storage", + "narwhal-types", + "narwhal-worker", + "prometheus", + "rand 0.8.5", + "reqwest", + "sui-keys", + "sui-protocol-config", + "sui-types", + "telemetry-subscribers", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "tracing-subscriber", + "url 2.4.1", + "workspace-hack", +] + +[[package]] +name = "narwhal-primary" +version = "0.1.0-canonical-sui" +dependencies = [ + "anemo", + "anemo-tower", + "anyhow", + "async-trait", + "backoff", + "bcs 0.1.6", + "bytes", + "cfg-if", + "fastcrypto", + "fastcrypto-tbls", + "futures 0.3.28", + "governor", + "itertools 0.10.5", + "mysten-common", + "mysten-metrics", + "mysten-network", + "narwhal-config", + "narwhal-crypto", + "narwhal-network", + "narwhal-storage", + "narwhal-types", + "once_cell", + "parking_lot 0.12.1", + "prometheus", + "rand 0.8.5", + "sui-macros", + "sui-protocol-config", + "tap", + "thiserror", + "tokio", + "tokio-stream", + "tower", + "tracing", + "typed-store", + "workspace-hack", +] + +[[package]] +name = "narwhal-storage" +version = "0.1.0-canonical-sui" +dependencies = [ + "fastcrypto", + "futures 0.3.28", + "lru", + "mysten-common", + "narwhal-config", + "narwhal-types", + "parking_lot 0.12.1", + "prometheus", + "sui-macros", + "tap", + "tempfile", + "tokio", + "tracing", + "typed-store", + "workspace-hack", +] + +[[package]] +name = "narwhal-test-utils" +version = "0.1.0-canonical-sui" +dependencies = [ + "anemo", + "fastcrypto", + "fdlimit", + "indexmap 1.9.3", + "itertools 0.10.5", + "mysten-metrics", + "mysten-network", + "narwhal-config", + "narwhal-crypto", + "narwhal-executor", + "narwhal-network", + "narwhal-node", + "narwhal-primary", + "narwhal-storage", + "narwhal-types", + "narwhal-worker", + "once_cell", + "prometheus", + "rand 0.8.5", + "sui-protocol-config", + "telemetry-subscribers", + "tempfile", + "tokio", + "tonic 0.10.2", + "tracing", + "typed-store", + "workspace-hack", +] + +[[package]] +name = "narwhal-types" +version = "0.1.0-canonical-sui" +dependencies = [ + "anemo", + "anemo-build", + "anyhow", + "base64 0.21.5", + "bcs 0.1.6", + "bytes", + "derive_builder", + "enum_dispatch", + "fastcrypto", + "fastcrypto-tbls", + "futures 0.3.28", + "indexmap 1.9.3", + "mockall", + "mysten-common", + "mysten-metrics", + "mysten-network", + "mysten-util-mem", + "narwhal-config", + "narwhal-crypto", + "once_cell", + "prometheus", + "proptest", + "proptest-derive", + "prost 0.12.1", + "prost-build 0.12.1", + "protobuf-src", + "rand 0.8.5", + "roaring", + "rustversion", + "serde 1.0.190", + "serde_with 2.3.3", + "sui-protocol-config", + "thiserror", + "tokio", + "tonic 0.10.2", + "tonic-build 0.10.2", + "tracing", + "typed-store", + "workspace-hack", +] + +[[package]] +name = "narwhal-worker" +version = "0.1.0-canonical-sui" +dependencies = [ + "anemo", + "anemo-tower", + "anyhow", + "arc-swap", + "async-trait", + "byteorder", + "bytes", + "eyre", + "fastcrypto", + "futures 0.3.28", + "governor", + "itertools 0.10.5", + "mysten-metrics", + "mysten-network", + "narwhal-config", + "narwhal-crypto", + "narwhal-network", + "narwhal-types", + "prometheus", + "rand 0.8.5", + "sui-protocol-config", + "tap", + "thiserror", + "tokio", + "tonic 0.10.2", + "tower", + "tracing", + "typed-store", + "workspace-hack", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static 1.4.0", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" +dependencies = [ + "lexical-core", + "memchr", + "version_check", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +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" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits 0.2.17", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits 0.2.17", + "rand 0.8.5", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static 1.4.0", + "libm", + "num-integer", + "num-iter", + "num-traits 0.2.17", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits 0.2.17", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits 0.2.17", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits 0.2.17", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits 0.2.17", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.17", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.3", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "object_store" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f930c88a43b1c3f6e776dfe495b4afab89882dbc81530c632db2ed65451ebcb4" +dependencies = [ + "async-trait", + "base64 0.21.5", + "bytes", + "chrono", + "futures 0.3.28", + "humantime", + "hyper", + "itertools 0.11.0", + "parking_lot 0.12.1", + "percent-encoding 2.3.0", + "quick-xml", + "rand 0.8.5", + "reqwest", + "ring 0.16.20", + "rustls-pemfile", + "serde 1.0.190", + "serde_json", + "snafu", + "tokio", + "tracing", + "url 2.4.1", + "walkdir", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.4", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "openssl" +version = "0.10.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +dependencies = [ + "bitflags 2.4.1", + "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 1.0.69", + "quote 1.0.33", + "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-sys" +version = "0.9.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5e5a5c4135864099f3faafbe939eb4d7f9b80ebf68a8448da961b32a7c1275" +dependencies = [ + "async-trait", + "futures-core", + "http", + "opentelemetry-proto", + "opentelemetry-semantic-conventions", + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "thiserror", + "tokio", + "tonic 0.9.2", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e3f814aa9f8c905d0ee4bde026afd3b2577a97c10e1699912e3e44f0c4cbeb" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "tonic 0.9.2", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c9f9340ad135068800e7f1b24e9e09ed9e7143f5bf8518ded3d3ec69789269" +dependencies = [ + "opentelemetry", +] + +[[package]] +name = "opentelemetry_api" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" +dependencies = [ + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "ordered-float 3.9.2", + "percent-encoding 2.3.0", + "rand 0.8.5", + "regex", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits 0.2.17", +] + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits 0.2.17", +] + +[[package]] +name = "ouroboros" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeff60e3e37407a80ead3e9458145b456e978c4068cddbfea6afb48572962ca" +dependencies = [ + "ouroboros_macro 0.9.5", + "stable_deref_trait", +] + +[[package]] +name = "ouroboros" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" +dependencies = [ + "aliasable", + "ouroboros_macro 0.15.6", +] + +[[package]] +name = "ouroboros" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" +dependencies = [ + "aliasable", + "ouroboros_macro 0.17.2", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03f2cb802b5bdfdf52f1ffa0b54ce105e4d346e91990dd571f86c91321ad49e2" +dependencies = [ + "Inflector", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ouroboros_macro" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" +dependencies = [ + "Inflector", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ouroboros_macro" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.8", + "elliptic-curve 0.13.6", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "papergrid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae7891b22598926e4398790c8fe6447930c72a67d36d983a49d6ce682ce83290" +dependencies = [ + "bytecount", + "fnv", + "unicode-width", +] + +[[package]] +name = "parity-scale-codec" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +dependencies = [ + "arrayvec 0.7.4", + "bitvec 0.20.4", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive 2.3.1", + "serde 1.0.190", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +dependencies = [ + "arrayvec 0.7.4", + "bitvec 1.0.1", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive 3.6.5", + "serde 1.0.190", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[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 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[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 = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "pest_meta" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "petgraph" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +dependencies = [ + "fixedbitset 0.2.0", + "indexmap 1.9.3", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset 0.4.2", + "indexmap 2.1.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +dependencies = [ + "der 0.6.1", + "pkcs8 0.9.0", + "spki 0.6.0", + "zeroize", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.8", + "pkcs8 0.10.2", + "spki 0.7.2", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.2", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" + +[[package]] +name = "poseidon-ark" +version = "0.0.1" +source = "git+https://github.com/arnaucube/poseidon-ark.git?rev=ff7f5e05d55667b4ffba129b837da780c4c5c849#ff7f5e05d55667b4ffba129b837da780c4c5c849" +dependencies = [ + "ark-bn254", + "ark-ff", + "ark-std", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "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-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 = "prefix-manager" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21965b29633f6d9b2ebc05ba4c348173389e38da66de71dcd0b2bd8b9cde713c" + +[[package]] +name = "pretty" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9940b913ee56ddd94aec2d3cd179dd47068236f42a1a6415ccf9d880ce2a61" +dependencies = [ + "arrayvec 0.5.2", + "typed-arena", +] + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2 1.0.69", + "syn 1.0.109", +] + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2 1.0.69", + "syn 2.0.39", +] + +[[package]] +name = "primeorder" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7dbe9ed3b56368bd99483eb32fe9c17fdd3730aebadc906918ce78d54c7eeb4" +dependencies = [ + "elliptic-curve 0.13.6", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "impl-codec 0.5.1", + "impl-serde 0.3.2", + "uint", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "impl-rlp", + "impl-serde 0.4.0", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[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 = "prometheus" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static 1.4.0", + "memchr", + "parking_lot 0.12.1", + "protobuf", + "thiserror", +] + +[[package]] +name = "prometheus-closure-metric" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "prometheus", + "protobuf", + "workspace-hack", +] + +[[package]] +name = "proptest" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.4.1", + "lazy_static 1.4.0", + "num-traits 0.2.17", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax 0.7.5", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "proptest-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90b46295382dc76166cb7cf2bb4a97952464e4b7ed5a43e6cd34e1fec3349ddc" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" +dependencies = [ + "bytes", + "prost-derive 0.12.1", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.10.5", + "lazy_static 1.4.0", + "log", + "multimap", + "petgraph 0.6.4", + "prettyplease 0.1.25", + "prost 0.11.9", + "prost-types 0.11.9", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-build" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bdf592881d821b83d471f8af290226c8d51402259e9bb5be7f9f8bdebbb11ac" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.11.0", + "log", + "multimap", + "once_cell", + "petgraph 0.6.4", + "prettyplease 0.2.15", + "prost 0.12.1", + "prost-types 0.12.1", + "regex", + "syn 2.0.39", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost 0.11.9", +] + +[[package]] +name = "prost-types" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e081b29f63d83a4bc75cfc9f3fe424f9156cf92d8a4f0c9407cce9a1b67327cf" +dependencies = [ + "prost 0.12.1", +] + +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +dependencies = [ + "bytes", +] + +[[package]] +name = "protobuf-src" +version = "1.1.0+21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ac8852baeb3cc6fb83b93646fb93c0ffe5d14bf138c945ceb4b9948ee0e3c1" +dependencies = [ + "autotools", +] + +[[package]] +name = "protoc-gen-prost" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10dfa031ad41fdcfb180de73ece3ed076250f1132a13ad6bba218699f612fb95" +dependencies = [ + "once_cell", + "prost 0.11.9", + "prost-build 0.11.9", + "prost-types 0.11.9", + "regex", +] + +[[package]] +name = "protoc-gen-tonic" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "725a07a704f9cf7a956b302c21d81b5516ed5ee6cfbbf827edb69beeaae6cc30" +dependencies = [ + "heck 0.4.1", + "prettyplease 0.1.25", + "prost 0.11.9", + "prost-build 0.11.9", + "prost-types 0.11.9", + "protoc-gen-prost", + "regex", + "syn 1.0.109", + "tonic-build 0.8.4", +] + +[[package]] +name = "ptree" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0de80796b316aec75344095a6d2ef68ec9b8f573b9e7adc821149ba3598e270" +dependencies = [ + "ansi_term", + "atty", + "config", + "directories", + "petgraph 0.6.4", + "serde 1.0.190", + "serde-value", + "tint", +] + +[[package]] +name = "quanta" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" +dependencies = [ + "crossbeam-utils", + "libc", + "mach2", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", + "serde 1.0.190", +] + +[[package]] +name = "quinn" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +dependencies = [ + "bytes", + "futures-io", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c78e758510582acc40acb90458401172d41f1016f8c9dde89e49677afb7eec1" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.16.20", + "rustc-hash", + "rustls", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +dependencies = [ + "bytes", + "libc", + "socket2 0.5.5", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2 1.0.69", +] + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[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" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "random-manager" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2557c07161d4d805cd7e711d0648b292be9e727d9678d078bab052278cd1b71" +dependencies = [ + "bs58 0.4.0", + "lazy_static 1.4.0", + "primitive-types 0.12.2", + "rand 0.8.5", + "ring 0.16.20", +] + +[[package]] +name = "raw-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" +dependencies = [ + "pem", + "ring 0.16.20", + "time", + "yasna", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem", + "ring 0.16.20", + "time", + "x509-parser 0.14.0", + "yasna", +] + +[[package]] +name = "readonly" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f439da1766942fe069954da6058b2e6c1760eb878bae76f5be9fc29f56f574" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "real_tokio" +version = "1.28.1" +source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.4.10", + "tokio-macros 2.1.0 (git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45)", + "windows-sys 0.48.0", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.10", + "libredox", + "thiserror", +] + +[[package]] +name = "ref-cast" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acde58d073e9c79da00f2b5b84eed919c8326832648a5b109b3fce1bb1175280" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding 2.3.0", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde 1.0.190", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util 0.7.10", + "tower-service", + "url 2.4.1", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "retain_mut" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086" + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac 0.12.1", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom 0.2.10", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "roaring" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6106b5cf8587f5834158895e9715a3c6c9716c8aefab57f1f7680917191c7873" +dependencies = [ + "bytemuck", + "byteorder", + "retain_mut", +] + +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rsa" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55a77d189da1fee555ad95b7e50e7457d91c0e089ec68ca69ad2989413bbdab4" +dependencies = [ + "byteorder", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits 0.2.17", + "pkcs1 0.4.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sha2 0.10.8", + "signature 2.1.0", + "subtle", + "zeroize", +] + +[[package]] +name = "rsa" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits 0.2.17", + "pkcs1 0.7.5", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "signature 2.1.0", + "spki 0.7.2", + "subtle", + "zeroize", +] + +[[package]] +name = "rust-embed" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "rust-embed-utils", + "syn 2.0.39", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +dependencies = [ + "sha2 0.10.8", + "walkdir", +] + +[[package]] +name = "rust-ini" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" + +[[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-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +dependencies = [ + "log", + "ring 0.17.5", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec 3.6.5", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "schemars" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +dependencies = [ + "dyn-clone", + "either", + "schemars_derive", + "serde 1.0.190", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "serde_derive_internals", + "syn 1.0.109", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", + "generic-array", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" + +[[package]] +name = "serde" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-generate" +version = "0.20.6" +source = "git+https://github.com/aptos-labs/serde-reflection?rev=839aed62a20ddccf043c08961cfe74875741ccba#839aed62a20ddccf043c08961cfe74875741ccba" +dependencies = [ + "bcs 0.1.6", + "bincode", + "heck 0.3.3", + "include_dir 0.6.2", + "maplit", + "serde 1.0.190", + "serde-reflection 0.3.5", + "serde_bytes", + "serde_yaml 0.8.26", + "structopt", + "textwrap 0.13.4", +] + +[[package]] +name = "serde-hjson" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" +dependencies = [ + "lazy_static 1.4.0", + "num-traits 0.1.43", + "regex", + "serde 0.8.23", +] + +[[package]] +name = "serde-name" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12c47087018ec281d1cdab673d36aea22d816b54d498264029c05d5fa1910da6" +dependencies = [ + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "serde-name" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b5b14ebbcc4e4f2b3642fa99c388649da58d1dc3308c7d109f39f565d1710f0" +dependencies = [ + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "serde-reflection" +version = "0.3.5" +source = "git+https://github.com/aptos-labs/serde-reflection?rev=839aed62a20ddccf043c08961cfe74875741ccba#839aed62a20ddccf043c08961cfe74875741ccba" +dependencies = [ + "once_cell", + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "serde-reflection" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05a5f801ac62a51a49d378fdb3884480041b99aced450b28990673e8ff99895" +dependencies = [ + "once_cell", + "serde 1.0.190", + "thiserror", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float 2.10.1", + "serde 1.0.190", +] + +[[package]] +name = "serde_bytes" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "serde_derive" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "indexmap 2.1.0", + "itoa", + "ryu", + "serde 1.0.190", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde 1.0.190", +] + +[[package]] +name = "serde_repr" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[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 1.0.190", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "indexmap 1.9.3", + "serde 1.0.190", + "serde_json", + "serde_with_macros 2.3.3", + "time", +] + +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64 0.21.5", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.1.0", + "serde 1.0.190", + "serde_json", + "serde_with_macros 3.4.0", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling 0.20.3", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling 0.20.3", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "serde_yaml" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +dependencies = [ + "indexmap 1.9.3", + "ryu", + "serde 1.0.190", + "yaml-rust", +] + +[[package]] +name = "serde_yaml" +version = "0.9.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" +dependencies = [ + "indexmap 2.1.0", + "itoa", + "ryu", + "serde 1.0.190", + "unsafe-libyaml", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static 1.4.0", +] + +[[package]] +name = "shared-crypto" +version = "0.0.0-canonical-sui" +dependencies = [ + "bcs 0.1.6", + "eyre", + "fastcrypto", + "serde 1.0.190", + "serde_repr", + "workspace-hack", +] + +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[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" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "similar" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597" + +[[package]] +name = "simplelog" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bc0ffd69814a9b251d43afcabf96dad1b29f5028378056257be9e3fecc9f720" +dependencies = [ + "chrono", + "log", + "termcolor", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slip10_ed25519" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be0ff28bf14f9610a342169084e87a4f435ad798ec528dc7579a3678fa9dc9a" +dependencies = [ + "hmac-sha512", +] + +[[package]] +name = "slug" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +dependencies = [ + "deunicode", + "wasm-bindgen", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "snafu" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +dependencies = [ + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "snap" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.8", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "standalone-sui-subnet" +version = "0.1.0" +dependencies = [ + "anyhow", + "aptos-types", + "async-channel", + "avalanche-types", + "base64 0.21.5", + "bcs 0.1.6", + "bytes", + "chrono", + "derivative", + "dirs 5.0.1", + "env_logger", + "futures 0.3.28", + "hex", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "log", + "movement-sdk", + "rand 0.8.5", + "serde 1.0.190", + "serde_json", + "serde_with 2.3.3", + "sui-adapter-latest", + "sui-types", + "tokio", + "tonic 0.8.3", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap 2.34.0", + "lazy_static 1.4.0", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.69", + "quote 1.0.33", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "sui-adapter-latest" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "leb128", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-bytecode-verifier 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "move-vm-profiler", + "move-vm-runtime 0.1.0-canonical-sui", + "move-vm-types 0.1.0-canonical-sui", + "parking_lot 0.12.1", + "serde 1.0.190", + "sui-macros", + "sui-move-natives-latest", + "sui-protocol-config", + "sui-types", + "sui-verifier-latest", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-adapter-v0" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "leb128", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-bytecode-verifier-v0", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "move-vm-profiler", + "move-vm-runtime-v0", + "move-vm-types 0.1.0-canonical-sui", + "once_cell", + "parking_lot 0.12.1", + "serde 1.0.190", + "sui-macros", + "sui-move-natives-v0", + "sui-protocol-config", + "sui-types", + "sui-verifier-v0", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-adapter-v1" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "leb128", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-bytecode-verifier-v1", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "move-vm-profiler", + "move-vm-runtime-v1", + "move-vm-types 0.1.0-canonical-sui", + "parking_lot 0.12.1", + "serde 1.0.190", + "sui-macros", + "sui-move-natives-v1", + "sui-protocol-config", + "sui-types", + "sui-verifier-v1", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-archival" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "byteorder", + "bytes", + "fastcrypto", + "futures 0.3.28", + "indicatif", + "num_enum", + "object_store", + "prometheus", + "rand 0.8.5", + "serde 1.0.190", + "sui-config", + "sui-simulator", + "sui-storage", + "sui-types", + "tokio", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-config" +version = "0.0.0-canonical-sui" +dependencies = [ + "anemo", + "anyhow", + "bcs 0.1.6", + "csv", + "dirs 4.0.0", + "fastcrypto", + "narwhal-config", + "once_cell", + "prometheus", + "rand 0.8.5", + "serde 1.0.190", + "serde_with 2.3.3", + "serde_yaml 0.8.26", + "sui-keys", + "sui-protocol-config", + "sui-simulator", + "sui-storage", + "sui-types", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-core" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "arc-swap", + "async-trait", + "bcs 0.1.6", + "bytes", + "chrono", + "dashmap", + "either", + "enum_dispatch", + "eyre", + "fastcrypto", + "fastcrypto-zkp", + "futures 0.3.28", + "im", + "indexmap 1.9.3", + "itertools 0.10.5", + "lru", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-package 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "mysten-common", + "mysten-metrics", + "mysten-network", + "mysticeti-core", + "narwhal-config", + "narwhal-crypto", + "narwhal-executor", + "narwhal-network", + "narwhal-node", + "narwhal-test-utils", + "narwhal-types", + "narwhal-worker", + "num_cpus", + "object_store", + "once_cell", + "parking_lot 0.12.1", + "prometheus", + "rand 0.8.5", + "rocksdb", + "scopeguard", + "serde 1.0.190", + "serde_json", + "serde_with 2.3.3", + "shared-crypto", + "signature 1.6.4", + "sui-archival", + "sui-config", + "sui-execution", + "sui-framework", + "sui-genesis-builder", + "sui-json-rpc-types", + "sui-macros", + "sui-move-build", + "sui-network", + "sui-protocol-config", + "sui-simulator", + "sui-storage", + "sui-swarm-config", + "sui-transaction-checks", + "sui-types", + "tap", + "telemetry-subscribers", + "tempfile", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tracing", + "typed-store", + "typed-store-derive", + "workspace-hack", + "zeroize", +] + +[[package]] +name = "sui-enum-compat-util" +version = "0.1.0-canonical-sui" +dependencies = [ + "serde_yaml 0.8.26", + "workspace-hack", +] + +[[package]] +name = "sui-execution" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-verifier 0.1.0-canonical-sui", + "move-bytecode-verifier-v0", + "move-bytecode-verifier-v1", + "move-vm-config", + "move-vm-runtime 0.1.0-canonical-sui", + "move-vm-runtime-v0", + "move-vm-runtime-v1", + "sui-adapter-latest", + "sui-adapter-v0", + "sui-adapter-v1", + "sui-move-natives-latest", + "sui-move-natives-v0", + "sui-move-natives-v1", + "sui-protocol-config", + "sui-types", + "sui-verifier-latest", + "sui-verifier-v0", + "sui-verifier-v1", + "workspace-hack", +] + +[[package]] +name = "sui-framework" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-package 0.1.0-canonical-sui", + "once_cell", + "serde 1.0.190", + "sui-move-build", + "sui-types", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-framework-snapshot" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "git-version", + "serde 1.0.190", + "serde_json", + "sui-framework", + "sui-protocol-config", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "sui-genesis-builder" +version = "0.0.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "camino", + "fastcrypto", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "prometheus", + "rand 0.8.5", + "serde 1.0.190", + "serde_with 2.3.3", + "serde_yaml 0.8.26", + "shared-crypto", + "sui-config", + "sui-execution", + "sui-framework", + "sui-framework-snapshot", + "sui-protocol-config", + "sui-simulator", + "sui-types", + "tempfile", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-json" +version = "0.0.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "fastcrypto", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "schemars", + "serde 1.0.190", + "serde_json", + "sui-framework", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "sui-json-rpc-types" +version = "0.0.0-canonical-sui" +dependencies = [ + "anyhow", + "bcs 0.1.6", + "colored", + "enum_dispatch", + "fastcrypto", + "itertools 0.10.5", + "json_to_table", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "mysten-metrics", + "schemars", + "serde 1.0.190", + "serde_json", + "serde_with 2.3.3", + "sui-enum-compat-util", + "sui-json", + "sui-macros", + "sui-protocol-config", + "sui-types", + "tabled", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-keys" +version = "0.0.0-canonical-sui" +dependencies = [ + "anyhow", + "bip32", + "fastcrypto", + "rand 0.8.5", + "serde 1.0.190", + "serde_json", + "shared-crypto", + "signature 1.6.4", + "slip10_ed25519", + "sui-types", + "tiny-bip39", + "workspace-hack", +] + +[[package]] +name = "sui-macros" +version = "0.7.0-canonical-sui" +dependencies = [ + "futures 0.3.28", + "once_cell", + "sui-proc-macros", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-move-build" +version = "0.0.0-canonical-sui" +dependencies = [ + "anyhow", + "fastcrypto", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-bytecode-verifier 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-compiler 0.0.1-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "move-package 0.1.0-canonical-sui", + "move-symbol-pool 0.1.0-canonical-sui", + "serde-reflection 0.3.6", + "sui-types", + "sui-verifier-latest", + "tempfile", + "workspace-hack", +] + +[[package]] +name = "sui-move-natives-latest" +version = "0.1.0-canonical-sui" +dependencies = [ + "bcs 0.1.6", + "better_any", + "fastcrypto", + "fastcrypto-zkp", + "linked-hash-map", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-stdlib", + "move-vm-runtime 0.1.0-canonical-sui", + "move-vm-types 0.1.0-canonical-sui", + "smallvec", + "sui-protocol-config", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "sui-move-natives-v0" +version = "0.1.0-canonical-sui" +dependencies = [ + "bcs 0.1.6", + "better_any", + "fastcrypto", + "fastcrypto-zkp", + "linked-hash-map", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-stdlib-v0", + "move-vm-runtime-v0", + "move-vm-types 0.1.0-canonical-sui", + "smallvec", + "sui-protocol-config", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "sui-move-natives-v1" +version = "0.1.0-canonical-sui" +dependencies = [ + "bcs 0.1.6", + "better_any", + "fastcrypto", + "fastcrypto-zkp", + "linked-hash-map", + "move-binary-format 0.0.3-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-stdlib-v1", + "move-vm-runtime-v1", + "move-vm-types 0.1.0-canonical-sui", + "smallvec", + "sui-protocol-config", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "sui-network" +version = "0.0.0-canonical-sui" +dependencies = [ + "anemo", + "anemo-build", + "anemo-tower", + "anyhow", + "dashmap", + "futures 0.3.28", + "governor", + "mysten-metrics", + "mysten-network", + "prometheus", + "rand 0.8.5", + "serde 1.0.190", + "sui-archival", + "sui-config", + "sui-storage", + "sui-swarm-config", + "sui-types", + "tap", + "tokio", + "tonic 0.10.2", + "tonic-build 0.10.2", + "tower", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-proc-macros" +version = "0.7.0-canonical-sui" +dependencies = [ + "msim-macros", + "proc-macro2 1.0.69", + "quote 1.0.33", + "sui-enum-compat-util", + "syn 2.0.39", + "workspace-hack", +] + +[[package]] +name = "sui-protocol-config" +version = "0.1.0-canonical-sui" +dependencies = [ + "clap 4.4.7", + "insta", + "schemars", + "serde 1.0.190", + "serde_with 2.3.3", + "sui-protocol-config-macros", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-protocol-config-macros" +version = "0.1.0-canonical-sui" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", + "workspace-hack", +] + +[[package]] +name = "sui-simulator" +version = "0.7.0-canonical-sui" +dependencies = [ + "anemo", + "anemo-tower", + "fastcrypto", + "lru", + "move-package 0.1.0-canonical-sui", + "msim", + "narwhal-network", + "rand 0.8.5", + "sui-framework", + "sui-move-build", + "sui-types", + "telemetry-subscribers", + "tempfile", + "tower", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-storage" +version = "0.1.0-canonical-sui" +dependencies = [ + "anyhow", + "async-trait", + "backoff", + "base64-url", + "bcs 0.1.6", + "byteorder", + "bytes", + "chrono", + "clap 4.4.7", + "eyre", + "fastcrypto", + "futures 0.3.28", + "hyper", + "hyper-rustls", + "indicatif", + "integer-encoding", + "itertools 0.10.5", + "lru", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "mysten-metrics", + "num_enum", + "object_store", + "parking_lot 0.12.1", + "percent-encoding 2.3.0", + "prometheus", + "reqwest", + "rocksdb", + "serde 1.0.190", + "sui-json-rpc-types", + "sui-protocol-config", + "sui-types", + "tap", + "telemetry-subscribers", + "tempfile", + "tokio", + "tracing", + "typed-store", + "typed-store-derive", + "url 2.4.1", + "workspace-hack", + "zstd", +] + +[[package]] +name = "sui-swarm-config" +version = "0.0.0-canonical-sui" +dependencies = [ + "anemo", + "anyhow", + "fastcrypto", + "move-bytecode-utils 0.1.0-canonical-sui", + "narwhal-config", + "prometheus", + "rand 0.8.5", + "serde 1.0.190", + "serde_with 2.3.3", + "serde_yaml 0.8.26", + "shared-crypto", + "sui-config", + "sui-genesis-builder", + "sui-protocol-config", + "sui-simulator", + "sui-types", + "tempfile", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-transaction-checks" +version = "0.1.0-canonical-sui" +dependencies = [ + "fastcrypto-zkp", + "once_cell", + "sui-config", + "sui-execution", + "sui-macros", + "sui-protocol-config", + "sui-types", + "tracing", + "workspace-hack", +] + +[[package]] +name = "sui-types" +version = "0.1.0-canonical-sui" +dependencies = [ + "anemo", + "anyhow", + "bcs 0.1.6", + "bincode", + "byteorder", + "derivative", + "derive_more", + "enum_dispatch", + "eyre", + "fastcrypto", + "fastcrypto-zkp", + "im", + "indexmap 1.9.3", + "itertools 0.10.5", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-command-line-common 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-disassembler 0.1.0-canonical-sui", + "move-ir-types 0.1.0-canonical-sui", + "move-vm-profiler", + "move-vm-test-utils 0.1.0-canonical-sui", + "move-vm-types 0.1.0-canonical-sui", + "mysten-metrics", + "mysten-network", + "narwhal-config", + "narwhal-crypto", + "once_cell", + "prometheus", + "proptest", + "proptest-derive", + "rand 0.8.5", + "roaring", + "schemars", + "serde 1.0.190", + "serde-name 0.2.1", + "serde_json", + "serde_with 2.3.3", + "shared-crypto", + "signature 1.6.4", + "static_assertions", + "strum", + "strum_macros", + "sui-enum-compat-util", + "sui-macros", + "sui-protocol-config", + "tap", + "thiserror", + "tonic 0.10.2", + "tracing", + "typed-store-error", + "workspace-hack", +] + +[[package]] +name = "sui-verifier-latest" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-abstract-stack", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-bytecode-verifier 0.1.0-canonical-sui", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "sui-verifier-v0" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-abstract-stack", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-bytecode-verifier-v0", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "sui-protocol-config", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "sui-verifier-v1" +version = "0.1.0-canonical-sui" +dependencies = [ + "move-abstract-stack", + "move-binary-format 0.0.3-canonical-sui", + "move-bytecode-utils 0.1.0-canonical-sui", + "move-bytecode-verifier-v1", + "move-core-types 0.0.4-canonical-sui", + "move-vm-config", + "sui-types", + "workspace-hack", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", + "unicode-xid 0.2.4", +] + +[[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 = "tabled" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce69a5028cd9576063ec1f48edb2c75339fd835e6094ef3e05b3a079bf594a6" +dependencies = [ + "papergrid", + "tabled_derive", + "unicode-width", +] + +[[package]] +name = "tabled_derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "telemetry-subscribers" +version = "0.2.0-canonical-sui" +dependencies = [ + "atomic_float", + "bytes", + "bytes-varint", + "clap 4.4.7", + "crossterm", + "futures 0.3.28", + "once_cell", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-proto", + "opentelemetry_api", + "prometheus", + "prost 0.11.9", + "tokio", + "tonic 0.9.2", + "tracing", + "tracing-appender", + "tracing-opentelemetry", + "tracing-subscriber", + "workspace-hack", +] + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "tera" +version = "1.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static 1.4.0", + "percent-encoding 2.3.0", + "pest", + "pest_derive", + "rand 0.8.5", + "regex", + "serde 1.0.190", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd05616119e612a8041ef58f2b578906cc2531a6069047ae092cfb86a325d835" +dependencies = [ + "smawk", + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "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", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde 1.0.190", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tint" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7af24570664a3074673dbbf69a65bdae0ae0b72f2949b1adfbacb736ee4d6896" +dependencies = [ + "lazy_static 0.2.11", +] + +[[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 0.8.5", + "rustc-hash", + "sha2 0.10.8", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "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-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand 0.8.5", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util 0.7.10", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.7" +source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "futures-util", + "hashbrown 0.12.3", + "pin-project-lite", + "real_tokio", + "slab", + "tracing", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde 1.0.190", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "flate2", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding 2.3.0", + "pin-project", + "prost 0.11.9", + "prost-derive 0.11.9", + "tokio", + "tokio-stream", + "tokio-util 0.7.10", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.5", + "bytes", + "flate2", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding 2.3.0", + "pin-project", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.5", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding 2.3.0", + "pin-project", + "prost 0.12.1", + "rustls", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease 0.1.25", + "proc-macro2 1.0.69", + "prost-build 0.11.9", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "tonic-build" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" +dependencies = [ + "prettyplease 0.2.15", + "proc-macro2 1.0.69", + "prost-build 0.12.1", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "tonic-health" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080964d45894b90273d2b1dd755fdd114560db8636bb41cea615213c45043c4d" +dependencies = [ + "async-stream", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tonic 0.9.2", +] + +[[package]] +name = "tonic-health" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f80db390246dfb46553481f6024f0082ba00178ea495dbb99e70ba9a4fafb5e1" +dependencies = [ + "async-stream", + "prost 0.12.1", + "tokio", + "tokio-stream", + "tonic 0.10.2", +] + +[[package]] +name = "tonic-reflection" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0543d7092032041fbeac1f2c84304537553421a11a623c2301b12ef0264862c7" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tokio", + "tokio-stream", + "tonic 0.9.2", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "hdrhistogram", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util 0.7.10", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "async-compression", + "base64 0.13.1", + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding 2.3.0", + "pin-project-lite", + "tokio", + "tokio-util 0.7.10", + "tower", + "tower-layer", + "tower-service", + "tracing", + "uuid", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "trace" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad0c048e114d19d1140662762bfdb10682f3bc806d8be18af846600214dd9af" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +dependencies = [ + "crossbeam-channel", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75327c6b667828ddc28f5e3f169036cb793c3f588d83bf0f262a7f062ffed3c8" +dependencies = [ + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde 1.0.190", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde 1.0.190", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "time", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "treeline" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror", + "url 2.4.1", + "utf-8", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typed-store" +version = "0.4.0-canonical-sui" +dependencies = [ + "async-trait", + "bcs 0.1.6", + "bincode", + "collectable", + "eyre", + "fdlimit", + "hdrhistogram", + "itertools 0.10.5", + "msim", + "once_cell", + "ouroboros 0.17.2", + "prometheus", + "rand 0.8.5", + "rocksdb", + "serde 1.0.190", + "sui-macros", + "tap", + "thiserror", + "tokio", + "tracing", + "typed-store-error", + "workspace-hack", +] + +[[package]] +name = "typed-store-derive" +version = "0.3.0-canonical-sui" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 1.0.109", + "workspace-hack", +] + +[[package]] +name = "typed-store-error" +version = "0.4.0-canonical-sui" +dependencies = [ + "serde 1.0.190", + "thiserror", + "workspace-hack", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" + +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +dependencies = [ + "idna 0.1.5", + "matches", + "percent-encoding 1.0.1", +] + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna 0.4.0", + "percent-encoding 2.3.0", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "getrandom 0.2.10", + "rand 0.8.5", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "variant_count" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" +dependencies = [ + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote 1.0.33", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "wasm-streams" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[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 = "workspace-hack" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beffa227304dbaea3ad6a06ac674f9bc83a3dec3b7f63eeb442de37e7cb6bb01" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "1.2.0" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs", + "base64 0.13.1", + "data-encoding", + "der-parser", + "lazy_static 1.4.0", + "nom 7.1.3", + "oid-registry", + "ring 0.16.20", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "x509-parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static 1.4.0", + "nom 7.1.3", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "zerocopy" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96f8f25c15a0edc9b07eb66e7e6e97d124c0505435c382fde1ab7ceb188aa956" +dependencies = [ + "byteorder", + "zerocopy-derive 0.6.5", +] + +[[package]] +name = "zerocopy" +version = "0.7.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" +dependencies = [ + "zerocopy-derive 0.7.25", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "855e0f6af9cd72b87d8a6c586f3cb583f5cdcc62c2c80869d8cd7e96fdf7ee20" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/canonical/Cargo.toml b/canonical/Cargo.toml new file mode 100644 index 000000000..f43d12285 --- /dev/null +++ b/canonical/Cargo.toml @@ -0,0 +1,54 @@ +[workspace] +resolver = "2" +members = [ + + "canonical-move-resolver", + "canonical-move-natives", + + "canonical-block-executor", + + "canonical-types" + +] + +[workspace.package] +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +authors = ["Liam Monninger "] +homepage = "https://www.movementlabs.xyz" +publish = false +repository = "https://github.com/movemntdev/m2" +rust-version = "1.70" + +# testing + +[workspace.dependencies] +# internal +canonical-types = { path = "../canonical-types" } + +# general +anyhow = "1.0.44" +futures = "0.3.17" +rand = "0.8.4" +bcs = "0.1.0" + +# aptos +aptos-framework = { path = "../vendors/aptos-core/aptos-move/framework" } +aptos-vm = { path = "../vendors/aptos-core/aptos-move/aptos-vm" } +aptos-types = { path = "../vendors/aptos-core/types" } +aptos-executor = { path = "../vendors/aptos-core/execution/executor" } +aptos-executor-types = { path = "../vendors/aptos-core/execution/executor-types" } +aptos-storage-interface = { path = "../vendors/aptos-core/storage/storage-interface" } + +# sui +sui-adapter-latest = { path = "../vendors/sui/sui-execution/latest/sui-adapter" } +sui-types = { path = "../vendors/sui/crates/sui-types" } +sui-core = { path = "../vendors/sui/crates/sui-core" } + +# movement +movement-sdk = { path = "../movement-sdk/movement-sdk" } + +# patches +[replace] +"move-abigen:0.1.0" = { path = "../vendors/sui/external-crates/move/move-prover/move-abigen" } \ No newline at end of file diff --git a/canonical/canonical-block-executor/Cargo.toml b/canonical/canonical-block-executor/Cargo.toml new file mode 100644 index 000000000..15a1300db --- /dev/null +++ b/canonical/canonical-block-executor/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "canonical-block-executor" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +avalanche-types = { version = "0.0.398", features = ["subnet", "codec_base64"] } +tokio = { version = "1.25.0", features = ["fs", "rt-multi-thread"] } +tonic = { version = "0.8.3", features = ["gzip"] } +serde = { version = "1.0.152", features = ["derive"] } +serde_json = "1.0.93" # https://github.com/serde-rs/json/releases +serde_with = { version = "2.2.0", features = ["hex"] } +log = "0.4.17" +dirs = "5.0.1" +hex = "0.4.3" +bytes = "1.4.0" +env_logger = "0.10.0" +base64 = { version = "0.21.0" } +chrono = "0.4.23" +derivative = "2.2.0" +jsonrpc-core = "18.0.0" +jsonrpc-core-client = { version = "18.0.0" } +jsonrpc-derive = "18.0.0" +async-channel = "1.9.0" + +anyhow = { workspace = true } +futures = { workspace = true } +rand = { workspace = true } +bcs = { workspace = true } +movement-sdk = { workspace = true } + +# sui +# todo: conflicting rocksdb means we can't use workspace +# todo: likely movement-sdk will move into its own workspace +# todo: once that happens, we can move sui into its own workspace +# todo: we will have to reconcile the two when we begin on the canonical VM +sui-adapter-latest = { workspace = true } +sui-types = { workspace = true } +sui-core = { workspace = true } diff --git a/canonical/canonical-block-executor/src/canonical_block_executor/mod.rs b/canonical/canonical-block-executor/src/canonical_block_executor/mod.rs new file mode 100644 index 000000000..a977943da --- /dev/null +++ b/canonical/canonical-block-executor/src/canonical_block_executor/mod.rs @@ -0,0 +1,71 @@ +use movement_sdk::{ExecutionLayer}; +use canonical_move_resolver::CanonicalMoveResolver; +use canonical_types::{Transaction, Block}; + +pub mod sui_block_executor; + +// todo: this will likely be a wrapper around some kind of +// todo: type-state pattern structs that handle the bootstrapping +// todo: or else we will move that to a higher order +// todo: good thing to consider for the movement_sdk +pub struct CanonicalBlockExecutionLayer<'state> { + move_resolver : CanonicalMoveResolver<'state> +} + +impl <'state> CanonicalBlockExecutionLayer<'state> { + + fn get_aptos_vm(){ + unimplemented!(); + } + + fn get_sui_executor(){ + unimplemented!(); + } + + /// Filters the block to just Aptos transactions. + fn get_aptos_block(block : Block){ + unimplemented!(); + } + + /// Filters the block to just Sui transactions. + /// Sui blocks are a fundamentally new construct. + /// Sui does not have blocks in its original form. + /// Concurrency considerations have not been made. + fn get_sui_block(block : Block){ + unimplemented!(); + } + + /// Executes a canonical block. + /// Canonical blocks in V1 are split into their respective transaction blocks. + /// This is done to accommodate a transaction flow that is compatible with their respective RPCs. + /// While Aptos has an original notion of blocks, Sui does not. + /// Aptos transactions will thus be executed concurrently, insofar as Block-STM allows. + /// Sui transactions will for now be executed sequentially. + /// The order of Sui and Aptos execution must be deterministic. + /// For now, we propose Sui transactions are executed first, then Aptos. + /// We can opt for a more balance strategy at a later date. + fn execute(block : Block){ + + // 1. Execute the Sui block. + let sui_block = self.get_sui_block(block); + let sui_executor = self.get_sui_executor(); + + // all sui transactions will be sequential for now + for transaction in sui_block { + + sui_executor.execute_transaction_to_effects( + transaction, + .... + ); + + } + + // 2. Execute the Aptos block + let aptos_block = self.get_aptos_block(block); + let aptos_executor = self.get_aptos_executor(); + aptos_executor.execute_block(aptos_block); + + + } + +} \ No newline at end of file diff --git a/canonical/canonical-block-executor/src/canonical_block_executor/sui_block_executor/README.md b/canonical/canonical-block-executor/src/canonical_block_executor/sui_block_executor/README.md new file mode 100644 index 000000000..276417aac --- /dev/null +++ b/canonical/canonical-block-executor/src/canonical_block_executor/sui_block_executor/README.md @@ -0,0 +1,4 @@ +# `sui-block-executor` +**Note**: This may be worthy of its own crate--even outside of the canonical development altogether--as we plan to reuse it in the future. + +Sui does not have blocks by default. However, it is possible to use Sui's notion of checkpoints to create an execution model that is similar to blocks. Furthermore, we can disentangle this execution from consensus by using the checkpoint runtime by itself. This is the approach currently adopted in this module. \ No newline at end of file diff --git a/canonical/canonical-block-executor/src/canonical_block_executor/sui_block_executor/mod.rs b/canonical/canonical-block-executor/src/canonical_block_executor/sui_block_executor/mod.rs new file mode 100644 index 000000000..f72504abc --- /dev/null +++ b/canonical/canonical-block-executor/src/canonical_block_executor/sui_block_executor/mod.rs @@ -0,0 +1,53 @@ +use std::sync::{ + Arc +}; + +use tokio::sync::{RwLock}; + +use sui_core::checkpoints::checkpoint_executor::{ + CheckpointExecutor +}; + +#[derive(Debug, Clone)] +pub struct SuiBlockExecutor { + checkpoint_executor: Arc> +} + +/*async fn init_executor_test( + buffer_size: usize, + store: Arc, +) -> ( + Arc, + CheckpointExecutor, + Arc, + Sender, + CommitteeFixture, +) { + let network_config = + sui_swarm_config::network_config_builder::ConfigBuilder::new_with_temp_dir().build(); + let state = TestAuthorityBuilder::new() + .with_network_config(&network_config) + .build() + .await; + + let (checkpoint_sender, _): (Sender, Receiver) = + broadcast::channel(buffer_size); + + let accumulator = StateAccumulator::new(state.database.clone()); + let accumulator = Arc::new(accumulator); + + let executor = CheckpointExecutor::new_for_tests( + checkpoint_sender.subscribe(), + store.clone(), + state.database.clone(), + state.transaction_manager().clone(), + accumulator.clone(), + ); + ( + state, + executor, + accumulator, + checkpoint_sender, + CommitteeFixture::from_network_config(&network_config), + ) +}*/ diff --git a/canonical/canonical-block-executor/src/lib.rs b/canonical/canonical-block-executor/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/canonical/canonical-move-natives/Cargo.toml b/canonical/canonical-move-natives/Cargo.toml new file mode 100644 index 000000000..e313416ae --- /dev/null +++ b/canonical/canonical-move-natives/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "canonical-move-natives" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +avalanche-types = { version = "0.0.398", features = ["subnet", "codec_base64"] } +tokio = { version = "1.25.0", features = ["fs", "rt-multi-thread"] } +tonic = { version = "0.8.3", features = ["gzip"] } +serde = { version = "1.0.152", features = ["derive"] } +serde_json = "1.0.93" # https://github.com/serde-rs/json/releases +serde_with = { version = "2.2.0", features = ["hex"] } +log = "0.4.17" +dirs = "5.0.1" +hex = "0.4.3" +bytes = "1.4.0" +env_logger = "0.10.0" +base64 = { version = "0.21.0" } +chrono = "0.4.23" +derivative = "2.2.0" +jsonrpc-core = "18.0.0" +jsonrpc-core-client = { version = "18.0.0" } +jsonrpc-derive = "18.0.0" +async-channel = "1.9.0" + +anyhow = { workspace = true } +futures = { workspace = true } +rand = { workspace = true } +bcs = { workspace = true } +movement-sdk = { workspace = true } + +# sui +# todo: conflicting rocksdb means we can't use workspace +# todo: likely movement-sdk will move into its own workspace +# todo: once that happens, we can move sui into its own workspace +# todo: we will have to reconcile the two when we begin on the canonical VM +sui-adapter-latest = { workspace = true } +sui-types = { workspace = true } diff --git a/canonical/canonical-move-natives/README.md b/canonical/canonical-move-natives/README.md new file mode 100644 index 000000000..995c67b8a --- /dev/null +++ b/canonical/canonical-move-natives/README.md @@ -0,0 +1,7 @@ +# `canonical-move-natives` +This crate is used to create the move function tables for both the `AptosVm` and `SuiExecutor` by wrapping over the `CanonicalMoveResolver`. + +In both cases, the natives table SHALL consist of +- Move stdlib natives (automatically compatible). +- Aptos natives (needs investigation). +- Sui natives (should be compatible via the resolver). \ No newline at end of file diff --git a/canonical/canonical-move-natives/src/canonical_move_natives/mod.rs b/canonical/canonical-move-natives/src/canonical_move_natives/mod.rs new file mode 100644 index 000000000..e69de29bb diff --git a/canonical/canonical-move-natives/src/lib.rs b/canonical/canonical-move-natives/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/canonical/canonical-move-resolver/Cargo.toml b/canonical/canonical-move-resolver/Cargo.toml new file mode 100644 index 000000000..3cab1a044 --- /dev/null +++ b/canonical/canonical-move-resolver/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "canonical-move-resolver" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +avalanche-types = { version = "0.0.398", features = ["subnet", "codec_base64"] } +tokio = { version = "1.25.0", features = ["fs", "rt-multi-thread"] } +tonic = { version = "0.8.3", features = ["gzip"] } +serde = { version = "1.0.152", features = ["derive"] } +serde_json = "1.0.93" # https://github.com/serde-rs/json/releases +serde_with = { version = "2.2.0", features = ["hex"] } +log = "0.4.17" +dirs = "5.0.1" +hex = "0.4.3" +bytes = "1.4.0" +env_logger = "0.10.0" +base64 = { version = "0.21.0" } +chrono = "0.4.23" +derivative = "2.2.0" +jsonrpc-core = "18.0.0" +jsonrpc-core-client = { version = "18.0.0" } +jsonrpc-derive = "18.0.0" +async-channel = "1.9.0" + +anyhow = { workspace = true } +futures = { workspace = true } +rand = { workspace = true } +bcs = { workspace = true } +movement-sdk = { workspace = true } + +# aptos +aptos-storage-interface = { workspace = true } + +# sui +# todo: conflicting rocksdb means we can't use workspace +# todo: likely movement-sdk will move into its own workspace +# todo: once that happens, we can move sui into its own workspace +# todo: we will have to reconcile the two when we begin on the canonical VM +sui-adapter-latest = { workspace = true } +sui-types = { workspace = true } diff --git a/canonical/canonical-move-resolver/README.md b/canonical/canonical-move-resolver/README.md new file mode 100644 index 000000000..6dc555f52 --- /dev/null +++ b/canonical/canonical-move-resolver/README.md @@ -0,0 +1 @@ +# Canonical VM \ No newline at end of file diff --git a/canonical/canonical-move-resolver/src/canonical_move_resolver/aptos.rs b/canonical/canonical-move-resolver/src/canonical_move_resolver/aptos.rs new file mode 100644 index 000000000..d3c89d8ba --- /dev/null +++ b/canonical/canonical-move-resolver/src/canonical_move_resolver/aptos.rs @@ -0,0 +1,5 @@ +/// An easy way to do this is actually to wrap over the reader-writer, +/// rather than directly implementing the move resolver. +mod db_reader_writer { + +} \ No newline at end of file diff --git a/canonical/canonical-move-resolver/src/canonical_move_resolver/mod.rs b/canonical/canonical-move-resolver/src/canonical_move_resolver/mod.rs new file mode 100644 index 000000000..51c58957f --- /dev/null +++ b/canonical/canonical-move-resolver/src/canonical_move_resolver/mod.rs @@ -0,0 +1,30 @@ +pub mod aptos; +pub mod sui; + +/// This is where the common resolver should be defined. +/// Essentially, it will be composed of a Sui resolver and an Aptos resolver. +/// First, we will check for an Aptos struct. +/// Then, we will check for a Sui object. + +// todo: skeleton +pub struct CommonResolver<'state> { + aptos_resolver : AptosResolver<'state>, + sui_resolver : SuiResolver<'state> +} + +// todo: skeleton +impl <'state>ResourceResolver for CommonResolver<'state> { + + fn get_resource() { + + // aptos resolver takes priority + match self.aptos_resolver.get_resource() { + Some(resource) => Some(resource), + None=>{ + self.sui_resolver.get_resource() + } + } + + } + +} \ No newline at end of file diff --git a/canonical/canonical-move-resolver/src/canonical_move_resolver/sui.rs b/canonical/canonical-move-resolver/src/canonical_move_resolver/sui.rs new file mode 100644 index 000000000..71ef8ef01 --- /dev/null +++ b/canonical/canonical-move-resolver/src/canonical_move_resolver/sui.rs @@ -0,0 +1,3 @@ +/*impl Into for { + +}*/ \ No newline at end of file diff --git a/canonical/canonical-move-resolver/src/lib.rs b/canonical/canonical-move-resolver/src/lib.rs new file mode 100644 index 000000000..729916a6c --- /dev/null +++ b/canonical/canonical-move-resolver/src/lib.rs @@ -0,0 +1,2 @@ +pub mod util; +pub mod canonical_move_resolver; \ No newline at end of file diff --git a/canonical/canonical-move-resolver/src/main.rs b/canonical/canonical-move-resolver/src/main.rs new file mode 100644 index 000000000..d83a47485 --- /dev/null +++ b/canonical/canonical-move-resolver/src/main.rs @@ -0,0 +1,3 @@ +pub fn main() { + unimplemented!() +} \ No newline at end of file diff --git a/canonical/canonical-move-resolver/src/util/mod.rs b/canonical/canonical-move-resolver/src/util/mod.rs new file mode 100644 index 000000000..e69de29bb diff --git a/canonical/canonical-rpc/Cargo.toml b/canonical/canonical-rpc/Cargo.toml new file mode 100644 index 000000000..4d5d13620 --- /dev/null +++ b/canonical/canonical-rpc/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "canonical-rpc" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +avalanche-types = { version = "0.0.398", features = ["subnet", "codec_base64"] } +tokio = { version = "1.25.0", features = ["fs", "rt-multi-thread"] } +tonic = { version = "0.8.3", features = ["gzip"] } +serde = { version = "1.0.152", features = ["derive"] } +serde_json = "1.0.93" # https://github.com/serde-rs/json/releases +serde_with = { version = "2.2.0", features = ["hex"] } +log = "0.4.17" +dirs = "5.0.1" +hex = "0.4.3" +bytes = "1.4.0" +env_logger = "0.10.0" +base64 = { version = "0.21.0" } +chrono = "0.4.23" +derivative = "2.2.0" +jsonrpc-core = "18.0.0" +jsonrpc-core-client = { version = "18.0.0" } +jsonrpc-derive = "18.0.0" +async-channel = "1.9.0" + +anyhow = { workspace = true } +futures = { workspace = true } +rand = { workspace = true } +bcs = { workspace = true } +movement-sdk = { workspace = true } + +# sui +# todo: conflicting rocksdb means we can't use workspace +# todo: likely movement-sdk will move into its own workspace +# todo: once that happens, we can move sui into its own workspace +# todo: we will have to reconcile the two when we begin on the canonical VM +sui-adapter-latest = { workspace = true } +sui-types = { workspace = true } diff --git a/canonical/canonical-rpc/README.md b/canonical/canonical-rpc/README.md new file mode 100644 index 000000000..b6f9785a9 --- /dev/null +++ b/canonical/canonical-rpc/README.md @@ -0,0 +1,6 @@ +# `canonical-rpc` +The canonical RPC is the complete RPC implementation for the Canonical Move VM. It contains: +- `canonical/` routes which are routes supporting the combined execution of Aptos and Sui. +- `aptos/` routes which are compatible with the upstream Aptos RPC. +- `sui/` routes which are compatible with the upstream Sui RPC. +- `movement/` routes which are derived as a consequence of implementing within the `movement-sdk` framework. \ No newline at end of file diff --git a/canonical/canonical-rpc/src/lib.rs b/canonical/canonical-rpc/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/canonical/canonical-types/Cargo.toml b/canonical/canonical-types/Cargo.toml new file mode 100644 index 000000000..a0bb537b1 --- /dev/null +++ b/canonical/canonical-types/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "standalone-sui-subnet" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +avalanche-types = { version = "0.0.398", features = ["subnet", "codec_base64"] } +tokio = { version = "1.25.0", features = ["fs", "rt-multi-thread"] } +tonic = { version = "0.8.3", features = ["gzip"] } +serde = { version = "1.0.152", features = ["derive"] } +serde_json = "1.0.93" # https://github.com/serde-rs/json/releases +serde_with = { version = "2.2.0", features = ["hex"] } +log = "0.4.17" +dirs = "5.0.1" +hex = "0.4.3" +bytes = "1.4.0" +env_logger = "0.10.0" +base64 = { version = "0.21.0" } +chrono = "0.4.23" +derivative = "2.2.0" +jsonrpc-core = "18.0.0" +jsonrpc-core-client = { version = "18.0.0" } +jsonrpc-derive = "18.0.0" +async-channel = "1.9.0" + +anyhow = { workspace = true } +futures = { workspace = true } +rand = { workspace = true } +bcs = { workspace = true } +movement-sdk = { workspace = true } + +# sui +sui-adapter-latest = { workspace = true } +sui-types = { workspace = true } + +aptos-types = { workspace = true} diff --git a/canonical/canonical-types/src/block/block.rs b/canonical/canonical-types/src/block/block.rs new file mode 100644 index 000000000..943380a06 --- /dev/null +++ b/canonical/canonical-types/src/block/block.rs @@ -0,0 +1,51 @@ +// todo: reduce import depth +use crate::transaction::transaction::Transaction; +use aptos_types::transaction::Transaction as AptosTransaction; + +#[derive(Clone, Debug)] +pub struct Block(Vec); + +impl Block { + + pub fn new(transactions: Vec) -> Self { + Block(transactions) + } + + /// Filters transactions to those enums which contain Aptos transactions. + pub fn filter_aptos_transactions(&self) -> Vec { + self.0.iter().filter(|t| t.is_aptos()).cloned().collect() + } + + /// Extracts Aptos transactions refs from the block. + pub fn extract_aptos_transaction_refs(&self) -> Vec<&AptosTransaction> { + self.0.iter().filter_map(|transactions| { + match transactions { + Transaction::Aptos(aptos_transaction) => Some(aptos_transaction), + _ => None + } + }).collect() + } + + /// Extracts Aptos transactions from the block. + pub fn extract_aptos_transactions(&self) -> Vec { + self.0.iter().filter_map(|transactions| { + match transactions { + Transaction::Aptos(aptos_transaction) => Some(aptos_transaction.clone()), + _ => None + } + }).collect() + } + +} + +impl Into> for Block { + fn into(self) -> Vec { + self.0 + } +} + +impl Into for Vec { + fn into(self) -> Block { + Block(self) + } +} \ No newline at end of file diff --git a/canonical/canonical-types/src/block/mod.rs b/canonical/canonical-types/src/block/mod.rs new file mode 100644 index 000000000..49bc7d4bf --- /dev/null +++ b/canonical/canonical-types/src/block/mod.rs @@ -0,0 +1 @@ +pub mod block; \ No newline at end of file diff --git a/canonical/canonical-types/src/lib.rs b/canonical/canonical-types/src/lib.rs new file mode 100644 index 000000000..cc8af46d5 --- /dev/null +++ b/canonical/canonical-types/src/lib.rs @@ -0,0 +1,2 @@ +pub mod transaction; +pub mod block; \ No newline at end of file diff --git a/canonical/canonical-types/src/transaction/mod.rs b/canonical/canonical-types/src/transaction/mod.rs new file mode 100644 index 000000000..be9dda049 --- /dev/null +++ b/canonical/canonical-types/src/transaction/mod.rs @@ -0,0 +1 @@ +pub mod transaction; \ No newline at end of file diff --git a/canonical/canonical-types/src/transaction/transaction.rs b/canonical/canonical-types/src/transaction/transaction.rs new file mode 100644 index 000000000..a99bbff1d --- /dev/null +++ b/canonical/canonical-types/src/transaction/transaction.rs @@ -0,0 +1,28 @@ +use aptos_types::transaction::{Transaction as AptosTransaction}; +use sui_types::transaction::{Transaction as SuiTransaction}; + +#[derive(Clone, Debug)] +pub enum Transaction { + Aptos(AptosTransaction), + Sui(SuiTransaction) +} + +impl Transaction { + + + + pub fn is_aptos(&self) -> bool { + match self { + Transaction::Aptos(_) => true, + Transaction::Sui(_) => false + } + } + + pub fn is_sui(&self) -> bool { + match self { + Transaction::Aptos(_) => false, + Transaction::Sui(_) => true + } + } + +} diff --git a/canonical/rust-toolchain b/canonical/rust-toolchain new file mode 100644 index 000000000..832e9afb6 --- /dev/null +++ b/canonical/rust-toolchain @@ -0,0 +1 @@ +1.70.0 diff --git a/canonical/rustfmt.toml b/canonical/rustfmt.toml new file mode 100644 index 000000000..f1c193bbc --- /dev/null +++ b/canonical/rustfmt.toml @@ -0,0 +1,11 @@ +combine_control_expr = false +edition = "2021" +imports_granularity = "Crate" +format_macro_matchers = true +group_imports = "One" +hex_literal_case = "Upper" +match_block_trailing_comma = true +newline_style = "Unix" +overflow_delimited_expr = true +reorder_impl_items = true +use_field_init_shorthand = true diff --git a/docker/compose/m1.local.dockercompose.yml b/docker/compose/m1.local.dockercompose.yml new file mode 100644 index 000000000..2c53c0f2d --- /dev/null +++ b/docker/compose/m1.local.dockercompose.yml @@ -0,0 +1,39 @@ +version: '3.8' + +services: + node_service: + build: + context: ../.. + dockerfile: services/local/subnet-request-proxy.dockerfile + ports: + - "3000:3000" # Replace with actual port numbers + networks: + - app-network + environment: + SUBNET_SOCKET_ADDRESS: 0.0.0.0:9650 + + ubuntu_service: + build: + context: ../.. + dockerfile: services/local/anr.dockerfile + ports: + - "9650:9650" + - "8090:8090" + - "8070:8070" + networks: + - app-network + + postgresql_service: + image: postgres:latest + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: postgres + ports: + - "5432:5432" + networks: + - app-network + +networks: + app-network: + driver: bridge diff --git a/docker/services/local/anr.dockerfile b/docker/services/local/anr.dockerfile new file mode 100644 index 000000000..d66674e2f --- /dev/null +++ b/docker/services/local/anr.dockerfile @@ -0,0 +1,28 @@ +# Use Ubuntu latest as the base image +FROM ubuntu:latest + +# Set the working directory in the container +WORKDIR /usr/src/app + +# Install necessary tools and dependencies +RUN apt-get update && apt-get install -y curl build-essential + +# Install Rust +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +ENV PATH="/root/.cargo/bin:${PATH}" + +# Install Go +RUN apt-get install -y golang + +# Copy the contents of your working directory to the container +COPY . . + +# Make the script executable +RUN chmod +x ./m1/scripts/run.debug.sh + +EXPOSE 9650 +EXPOSE 8070 +EXPOSE 8090 + +# Run the script +CMD cd ./m1 && ./scripts/run.debug.sh diff --git a/docker/services/local/subnet-request-proxy.dockerfile b/docker/services/local/subnet-request-proxy.dockerfile new file mode 100644 index 000000000..908a1c81b --- /dev/null +++ b/docker/services/local/subnet-request-proxy.dockerfile @@ -0,0 +1,29 @@ +# Use Node.js version 20 as the base image +FROM node:20 + +# Set the working directory inside the container +WORKDIR /usr/src/app + +# Copy package.json and package-lock.json (or yarn.lock) from your local directory to the container +COPY ./m1/subnet-request-proxy/package*.json ./ +# If you are using yarn, you might want to copy yarn.lock instead +# COPY ./m1/subnet-request-proxy/yarn.lock ./ + +# Install dependencies +RUN npm install +# If you are using yarn, use this command instead +# RUN yarn install + +# Copy the rest of your application's source code from your local directory to the container +COPY ./m1/subnet-request-proxy . + +# Set environment variables +ENV PORT=3000 +ENV SUBNET_ALIAS=subnet +ENV SUBNET_SOCKET_ADDRESS="0.0.0.0:9650" + +# Expose the port the app runs on +EXPOSE ${PORT} + +# Define the command to run your app (make sure app.js is the entry point of your app) +CMD ["node", "app.js"] diff --git a/m1/.gitignore b/m1/.gitignore index f2f9e58ec..28b51c0f9 100644 --- a/m1/.gitignore +++ b/m1/.gitignore @@ -1,2 +1,4 @@ target -Cargo.lock \ No newline at end of file +Cargo.lock +avalanchego +plugins \ No newline at end of file diff --git a/m1/Cargo.toml b/m1/Cargo.toml index cf49f9a37..ae2db931b 100644 --- a/m1/Cargo.toml +++ b/m1/Cargo.toml @@ -4,6 +4,7 @@ members = [ "subnet", "movement", "movement-benchmark", + "tests/e2e" ] [workspace.package] @@ -70,179 +71,179 @@ jemallocator = { version = "0.3.2", features = [ ] } # MOVE DEPENDENCIES -move-abigen = { path = "../third-party/aptos-core-1.7/third_party/move/move-prover/move-abigen" } -move-binary-format = { path = "../third-party/aptos-core-1.7/third_party/move/move-binary-format" } -move-bytecode-verifier = { path = "../third-party/aptos-core-1.7/third_party/move/move-bytecode-verifier" } -move-bytecode-utils = { path = "../third-party/aptos-core-1.7/third_party/move/tools/move-bytecode-utils" } -move-cli = { path = "../third-party/aptos-core-1.7/third_party/move/tools/move-cli" } -move-command-line-common = { path = "../third-party/aptos-core-1.7/third_party/move/move-command-line-common" } -move-coverage = { path = "../third-party/aptos-core-1.7/third_party/move/tools/move-coverage" } -move-compiler = { path = "../third-party/aptos-core-1.7/third_party/move/move-compiler" } -move-core-types = { path = "../third-party/aptos-core-1.7/third_party/move/move-core/types" } -move-docgen = { path = "../third-party/aptos-core-1.7/third_party/move/move-prover/move-docgen" } -move-disassembler = { path = "../third-party/aptos-core-1.7/third_party/move/tools/move-disassembler" } -move-ir-types = { path = "../third-party/aptos-core-1.7/third_party/move/move-ir/types" } -move-ir-compiler = { path = "../third-party/aptos-core-1.7/third_party/move/move-ir-compiler" } -move-bytecode-source-map = { path = "../third-party/aptos-core-1.7/third_party/move/move-ir-compiler/move-bytecode-source-map" } -move-model = { path = "../third-party/aptos-core-1.7/third_party/move/move-model" } -move-package = { path = "../third-party/aptos-core-1.7/third_party/move/tools/move-package" } -move-prover = { path = "../third-party/aptos-core-1.7/third_party/move/move-prover" } -move-prover-boogie-backend = { path = "../third-party/aptos-core-1.7/third_party/move/move-prover/boogie-backend" } -move-stackless-bytecode = { path = "../third-party/aptos-core-1.7/third_party/move/move-prover/bytecode" } +move-abigen = { path = "../vendors/aptos-core-1.7/third_party/move/move-prover/move-abigen" } +move-binary-format = { path = "../vendors/aptos-core-1.7/third_party/move/move-binary-format" } +move-bytecode-verifier = { path = "../vendors/aptos-core-1.7/third_party/move/move-bytecode-verifier" } +move-bytecode-utils = { path = "../vendors/aptos-core-1.7/third_party/move/tools/move-bytecode-utils" } +move-cli = { path = "../vendors/aptos-core-1.7/third_party/move/tools/move-cli" } +move-command-line-common = { path = "../vendors/aptos-core-1.7/third_party/move/move-command-line-common" } +move-coverage = { path = "../vendors/aptos-core-1.7/third_party/move/tools/move-coverage" } +move-compiler = { path = "../vendors/aptos-core-1.7/third_party/move/move-compiler" } +move-core-types = { path = "../vendors/aptos-core-1.7/third_party/move/move-core/types" } +move-docgen = { path = "../vendors/aptos-core-1.7/third_party/move/move-prover/move-docgen" } +move-disassembler = { path = "../vendors/aptos-core-1.7/third_party/move/tools/move-disassembler" } +move-ir-types = { path = "../vendors/aptos-core-1.7/third_party/move/move-ir/types" } +move-ir-compiler = { path = "../vendors/aptos-core-1.7/third_party/move/move-ir-compiler" } +move-bytecode-source-map = { path = "../vendors/aptos-core-1.7/third_party/move/move-ir-compiler/move-bytecode-source-map" } +move-model = { path = "../vendors/aptos-core-1.7/third_party/move/move-model" } +move-package = { path = "../vendors/aptos-core-1.7/third_party/move/tools/move-package" } +move-prover = { path = "../vendors/aptos-core-1.7/third_party/move/move-prover" } +move-prover-boogie-backend = { path = "../vendors/aptos-core-1.7/third_party/move/move-prover/boogie-backend" } +move-stackless-bytecode = { path = "../vendors/aptos-core-1.7/third_party/move/move-prover/bytecode" } aptos-move-stdlib = { path = "aptos-move/framework/move-stdlib" } -move-prover-test-utils = { path = "../third-party/aptos-core-1.7/third_party/move/move-prover/test-utils" } -move-resource-viewer = { path = "../third-party/aptos-core-1.7/third_party/move/tools/move-resource-viewer" } -move-symbol-pool = { path = "../third-party/aptos-core-1.7/third_party/move/move-symbol-pool" } -move-table-extension = { path = "../third-party/aptos-core-1.7/third_party/move/extensions/move-table-extension" } -move-transactional-test-runner = { path = "../third-party/aptos-core-1.7/third_party/move/testing-infra/transactional-test-runner" } -move-unit-test = { path = "../third-party/aptos-core-1.7/third_party/move/tools/move-unit-test", features = ["table-extension"] } -move-vm-runtime = { path = "../third-party/aptos-core-1.7/third_party/move/move-vm/runtime" } -move-vm-test-utils = { path = "../third-party/aptos-core-1.7/third_party/move/move-vm/test-utils", features = ["table-extension"] } -move-vm-types = { path = "../third-party/aptos-core-1.7/third_party/move/move-vm/types" } -read-write-set = { path = "../third-party/aptos-core-1.7/third_party/move/tools/read-write-set" } -read-write-set-dynamic = { path = "../third-party/aptos-core-1.7/third_party/move/tools/read-write-set/dynamic" } +move-prover-test-utils = { path = "../vendors/aptos-core-1.7/third_party/move/move-prover/test-utils" } +move-resource-viewer = { path = "../vendors/aptos-core-1.7/third_party/move/tools/move-resource-viewer" } +move-symbol-pool = { path = "../vendors/aptos-core-1.7/third_party/move/move-symbol-pool" } +move-table-extension = { path = "../vendors/aptos-core-1.7/third_party/move/extensions/move-table-extension" } +move-transactional-test-runner = { path = "../vendors/aptos-core-1.7/third_party/move/testing-infra/transactional-test-runner" } +move-unit-test = { path = "../vendors/aptos-core-1.7/third_party/move/tools/move-unit-test", features = ["table-extension"] } +move-vm-runtime = { path = "../vendors/aptos-core-1.7/third_party/move/move-vm/runtime" } +move-vm-test-utils = { path = "../vendors/aptos-core-1.7/third_party/move/move-vm/test-utils", features = ["table-extension"] } +move-vm-types = { path = "../vendors/aptos-core-1.7/third_party/move/move-vm/types" } +read-write-set = { path = "../vendors/aptos-core-1.7/third_party/move/tools/read-write-set" } +read-write-set-dynamic = { path = "../vendors/aptos-core-1.7/third_party/move/tools/read-write-set/dynamic" } # aptos # TODO: pleas remove unused dependencies -aptos = { path = "../third-party/aptos-core-1.7/crates/aptos" } -aptos-accumulator = { path = "../third-party/aptos-core-1.7/storage/accumulator" } -aptos-aggregator = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-aggregator" } -aptos-api = { path = "../third-party/aptos-core-1.7/api" } -aptos-api-test-context = { path = "../third-party/aptos-core-1.7/api/test-context" } -aptos-api-types = { path = "../third-party/aptos-core-1.7/api/types" } -aptos-backup-cli = { path = "../third-party/aptos-core-1.7/storage/backup/backup-cli" } -aptos-backup-service = { path = "../third-party/aptos-core-1.7/storage/backup/backup-service" } -aptos-bounded-executor = { path = "../third-party/aptos-core-1.7/crates/bounded-executor" } -aptos-block-executor = { path = "../third-party/aptos-core-1.7/aptos-move/block-executor" } -aptos-bitvec = { path = "../third-party/aptos-core-1.7/crates/aptos-bitvec" } -aptos-build-info = { path = "../third-party/aptos-core-1.7/crates/aptos-build-info" } -aptos-cached-packages = { path = "../third-party/aptos-core-1.7/aptos-move/framework/cached-packages" } -aptos-channels = { path = "../third-party/aptos-core-1.7/crates/channel" } -aptos-cli-common = { path = "../third-party/aptos-core-1.7/crates/aptos-cli-common" } -aptos-compression = { path = "../third-party/aptos-core-1.7/crates/aptos-compression" } -aptos-consensus = { path = "../third-party/aptos-core-1.7/consensus" } -aptos-consensus-notifications = { path = "../third-party/aptos-core-1.7/state-sync/inter-component/consensus-notifications" } -aptos-consensus-types = { path = "../third-party/aptos-core-1.7/consensus/consensus-types" } -aptos-config = { path = "../third-party/aptos-core-1.7/config" } -aptos-crash-handler = { path = "../third-party/aptos-core-1.7/crates/crash-handler" } -aptos-crypto = { path = "../third-party/aptos-core-1.7/crates/aptos-crypto" } -aptos-crypto-derive = { path = "../third-party/aptos-core-1.7/crates/aptos-crypto-derive" } -aptos-data-client = { path = "../third-party/aptos-core-1.7/state-sync/aptos-data-client" } -aptos-data-streaming-service = { path = "../third-party/aptos-core-1.7/state-sync/state-sync-v2/data-streaming-service" } -aptos-db = { path = "../third-party/aptos-core-1.7/storage/aptosdb" } -aptos-db-indexer = { path = "../third-party/aptos-core-1.7/storage/indexer" } -aptos-db-tool = { path = "../third-party/aptos-core-1.7/storage/db-tool" } -aptos-debugger = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-debugger" } -aptos-event-notifications = { path = "../third-party/aptos-core-1.7/state-sync/inter-component/event-notifications" } -aptos-executable-store = { path = "../third-party/aptos-core-1.7/storage/executable-store" } -aptos-executor = { path = "../third-party/aptos-core-1.7/execution/executor" } -aptos-block-partitioner = { path = "../third-party/aptos-core-1.7/execution/block-partitioner" } -aptos-enum-conversion-derive = { path = "../third-party/aptos-core-1.7/crates/aptos-enum-conversion-derive" } -aptos-executor-service = { path = "../third-party/aptos-core-1.7/execution/executor-service" } -aptos-executor-test-helpers = { path = "../third-party/aptos-core-1.7/execution/executor-test-helpers" } -aptos-executor-types = { path = "../third-party/aptos-core-1.7/execution/executor-types" } -aptos-faucet-cli = { path = "../third-party/aptos-core-1.7/crates/aptos-faucet/cli" } -aptos-faucet-core = { path = "../third-party/aptos-core-1.7/crates/aptos-faucet/core" } -aptos-faucet-service = { path = "../third-party/aptos-core-1.7/crates/aptos-faucet/service" } -aptos-faucet-metrics-server = { path = "../third-party/aptos-core-1.7/crates/aptos-faucet/metrics-server" } -aptos-fallible = { path = "../third-party/aptos-core-1.7/crates/fallible" } -aptos-forge = { path = "../third-party/aptos-core-1.7/testsuite/forge" } -aptos-framework = { path = "../third-party/aptos-core-1.7/aptos-move/framework" } -aptos-fuzzer = { path = "../third-party/aptos-core-1.7/testsuite/aptos-fuzzer" } -fuzzer = { path = "../third-party/aptos-core-1.7/testsuite/fuzzer" } -aptos-gas = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-gas" } -aptos-gas-algebra-ext = { path = "../third-party/aptos-core-1.7/aptos-move/gas-algebra-ext" } -aptos-gas-profiling = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-gas-profiling" } -aptos-genesis = { path = "../third-party/aptos-core-1.7/crates/aptos-genesis" } -aptos-github-client = { path = "../third-party/aptos-core-1.7/secure/storage/github" } -aptos-global-constants = { path = "../third-party/aptos-core-1.7/config/global-constants" } -aptos-id-generator = { path = "../third-party/aptos-core-1.7/crates/aptos-id-generator" } -aptos-indexer = { path = "../third-party/aptos-core-1.7/crates/indexer" } -aptos-indexer-grpc-cache-worker = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-cache-worker" } -aptos-indexer-grpc-data-service = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-data-service" } -aptos-indexer-grpc-file-store = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-file-store" } -aptos-indexer-grpc-post-processor = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-post-processor" } -aptos-indexer-grpc-fullnode = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-fullnode" } -aptos-indexer-grpc-utils = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-utils" } -aptos-indexer-grpc-parser = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-parser" } -aptos-indexer-grpc-server-framework = { path = "../third-party/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-server-framework" } -aptos-infallible = { path = "../third-party/aptos-core-1.7/crates/aptos-infallible" } -aptos-inspection-service = { path = "../third-party/aptos-core-1.7/crates/aptos-inspection-service" } -aptos-jellyfish-merkle = { path = "../third-party/aptos-core-1.7/storage/jellyfish-merkle" } -aptos-keygen = { path = "../third-party/aptos-core-1.7/crates/aptos-keygen" } -aptos-language-e2e-tests = { path = "../third-party/aptos-core-1.7/aptos-move/e2e-tests" } -aptos-ledger = { path = "../third-party/aptos-core-1.7/crates/aptos-ledger" } -aptos-log-derive = { path = "../third-party/aptos-core-1.7/crates/aptos-log-derive" } -aptos-logger = { path = "../third-party/aptos-core-1.7/crates/aptos-logger" } -aptos-memory-usage-tracker = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-memory-usage-tracker" } -aptos-mempool = { path = "../third-party/aptos-core-1.7/mempool" } -aptos-mempool-notifications = { path = "../third-party/aptos-core-1.7/state-sync/inter-component/mempool-notifications" } -aptos-memsocket = { path = "../third-party/aptos-core-1.7/network/memsocket" } -aptos-metrics-core = { path = "../third-party/aptos-core-1.7/crates/aptos-metrics-core" } -aptos-move-examples = { path = "../third-party/aptos-core-1.7/aptos-move/move-examples" } -aptos-moving-average = { path = "../third-party/aptos-core-1.7/crates/moving-average" } -aptos-mvhashmap = { path = "../third-party/aptos-core-1.7/aptos-move/mvhashmap" } -aptos-netcore = { path = "../third-party/aptos-core-1.7/network/netcore" } -aptos-network = { path = "../third-party/aptos-core-1.7/network" } -aptos-network-builder = { path = "../third-party/aptos-core-1.7/network/builder" } -aptos-network-checker = { path = "../third-party/aptos-core-1.7/crates/aptos-network-checker" } -aptos-network-discovery = { path = "../third-party/aptos-core-1.7/network/discovery" } -aptos-node = { path = "../third-party/aptos-core-1.7/aptos-node" } -aptos-node-checker = { path = "../third-party/aptos-core-1.7/ecosystem/node-checker" } -aptos-node-identity = { path = "../third-party/aptos-core-1.7/crates/aptos-node-identity" } -aptos-node-resource-metrics = { path = "../third-party/aptos-core-1.7/crates/node-resource-metrics" } -aptos-num-variants = { path = "../third-party/aptos-core-1.7/crates/num-variants" } -aptos-openapi = { path = "../third-party/aptos-core-1.7/crates/aptos-openapi" } -aptos-package-builder = { path = "../third-party/aptos-core-1.7/aptos-move/package-builder" } -aptos-peer-monitoring-service-client = { path = "../third-party/aptos-core-1.7/network/peer-monitoring-service/client" } -aptos-peer-monitoring-service-server = { path = "../third-party/aptos-core-1.7/network/peer-monitoring-service/server" } -aptos-peer-monitoring-service-types = { path = "../third-party/aptos-core-1.7/network/peer-monitoring-service/types" } -aptos-proptest-helpers = { path = "../third-party/aptos-core-1.7/crates/aptos-proptest-helpers" } -aptos-protos = { path = "../third-party/aptos-core-1.7/crates/aptos-protos" } -aptos-proxy = { path = "../third-party/aptos-core-1.7/crates/proxy" } -aptos-push-metrics = { path = "../third-party/aptos-core-1.7/crates/aptos-push-metrics" } -aptos-rate-limiter = { path = "../third-party/aptos-core-1.7/crates/aptos-rate-limiter" } -aptos-release-builder = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-release-builder" } -aptos-resource-viewer = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-resource-viewer" } -aptos-rest-client = { path = "../third-party/aptos-core-1.7/crates/aptos-rest-client" } -aptos-retrier = { path = "../third-party/aptos-core-1.7/crates/aptos-retrier" } -aptos-rocksdb-options = { path = "../third-party/aptos-core-1.7/storage/rocksdb-options" } -aptos-rosetta = { path = "../third-party/aptos-core-1.7/crates/aptos-rosetta" } -aptos-runtimes = { path = "../third-party/aptos-core-1.7/crates/aptos-runtimes" } -aptos-safety-rules = { path = "../third-party/aptos-core-1.7/consensus/safety-rules" } -aptos-schemadb = { path = "../third-party/aptos-core-1.7/storage/schemadb" } -aptos-scratchpad = { path = "../third-party/aptos-core-1.7/storage/scratchpad" } -aptos-sdk = { path = "../third-party/aptos-core-1.7/sdk" } -aptos-sdk-builder = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-sdk-builder" } -aptos-secure-net = { path = "../third-party/aptos-core-1.7/secure/net" } -aptos-secure-storage = { path = "../third-party/aptos-core-1.7/secure/storage" } -aptos-short-hex-str = { path = "../third-party/aptos-core-1.7/crates/short-hex-str" } -aptos-speculative-state-helper = { path = "../third-party/aptos-core-1.7/crates/aptos-speculative-state-helper" } -aptos-state-sync-driver = { path = "../third-party/aptos-core-1.7/state-sync/state-sync-v2/state-sync-driver" } -aptos-state-view = { path = "../third-party/aptos-core-1.7/storage/state-view" } -aptos-storage-interface = { path = "../third-party/aptos-core-1.7/storage/storage-interface" } -aptos-storage-service-client = { path = "../third-party/aptos-core-1.7/state-sync/storage-service/client" } -aptos-storage-service-notifications = { path = "../third-party/aptos-core-1.7/state-sync/inter-component/storage-service-notifications" } -aptos-storage-service-types = { path = "../third-party/aptos-core-1.7/state-sync/storage-service/types" } -aptos-storage-service-server = { path = "../third-party/aptos-core-1.7/state-sync/storage-service/server" } -aptos-telemetry = { path = "../third-party/aptos-core-1.7/crates/aptos-telemetry" } -aptos-telemetry-service = { path = "../third-party/aptos-core-1.7/crates/aptos-telemetry-service" } -aptos-temppath = { path = "../third-party/aptos-core-1.7/crates/aptos-temppath" } -aptos-testcases = { path = "../third-party/aptos-core-1.7/testsuite/testcases" } -aptos-time-service = { path = "../third-party/aptos-core-1.7/crates/aptos-time-service", features = [ +aptos = { path = "../vendors/aptos-core-1.7/crates/aptos" } +aptos-accumulator = { path = "../vendors/aptos-core-1.7/storage/accumulator" } +aptos-aggregator = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-aggregator" } +aptos-api = { path = "../vendors/aptos-core-1.7/api" } +aptos-api-test-context = { path = "../vendors/aptos-core-1.7/api/test-context" } +aptos-api-types = { path = "../vendors/aptos-core-1.7/api/types" } +aptos-backup-cli = { path = "../vendors/aptos-core-1.7/storage/backup/backup-cli" } +aptos-backup-service = { path = "../vendors/aptos-core-1.7/storage/backup/backup-service" } +aptos-bounded-executor = { path = "../vendors/aptos-core-1.7/crates/bounded-executor" } +aptos-block-executor = { path = "../vendors/aptos-core-1.7/aptos-move/block-executor" } +aptos-bitvec = { path = "../vendors/aptos-core-1.7/crates/aptos-bitvec" } +aptos-build-info = { path = "../vendors/aptos-core-1.7/crates/aptos-build-info" } +aptos-cached-packages = { path = "../vendors/aptos-core-1.7/aptos-move/framework/cached-packages" } +aptos-channels = { path = "../vendors/aptos-core-1.7/crates/channel" } +aptos-cli-common = { path = "../vendors/aptos-core-1.7/crates/aptos-cli-common" } +aptos-compression = { path = "../vendors/aptos-core-1.7/crates/aptos-compression" } +aptos-consensus = { path = "../vendors/aptos-core-1.7/consensus" } +aptos-consensus-notifications = { path = "../vendors/aptos-core-1.7/state-sync/inter-component/consensus-notifications" } +aptos-consensus-types = { path = "../vendors/aptos-core-1.7/consensus/consensus-types" } +aptos-config = { path = "../vendors/aptos-core-1.7/config" } +aptos-crash-handler = { path = "../vendors/aptos-core-1.7/crates/crash-handler" } +aptos-crypto = { path = "../vendors/aptos-core-1.7/crates/aptos-crypto" } +aptos-crypto-derive = { path = "../vendors/aptos-core-1.7/crates/aptos-crypto-derive" } +aptos-data-client = { path = "../vendors/aptos-core-1.7/state-sync/aptos-data-client" } +aptos-data-streaming-service = { path = "../vendors/aptos-core-1.7/state-sync/state-sync-v2/data-streaming-service" } +aptos-db = { path = "../vendors/aptos-core-1.7/storage/aptosdb" } +aptos-db-indexer = { path = "../vendors/aptos-core-1.7/storage/indexer" } +aptos-db-tool = { path = "../vendors/aptos-core-1.7/storage/db-tool" } +aptos-debugger = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-debugger" } +aptos-event-notifications = { path = "../vendors/aptos-core-1.7/state-sync/inter-component/event-notifications" } +aptos-executable-store = { path = "../vendors/aptos-core-1.7/storage/executable-store" } +aptos-executor = { path = "../vendors/aptos-core-1.7/execution/executor" } +aptos-block-partitioner = { path = "../vendors/aptos-core-1.7/execution/block-partitioner" } +aptos-enum-conversion-derive = { path = "../vendors/aptos-core-1.7/crates/aptos-enum-conversion-derive" } +aptos-executor-service = { path = "../vendors/aptos-core-1.7/execution/executor-service" } +aptos-executor-test-helpers = { path = "../vendors/aptos-core-1.7/execution/executor-test-helpers" } +aptos-executor-types = { path = "../vendors/aptos-core-1.7/execution/executor-types" } +aptos-faucet-cli = { path = "../vendors/aptos-core-1.7/crates/aptos-faucet/cli" } +aptos-faucet-core = { path = "../vendors/aptos-core-1.7/crates/aptos-faucet/core" } +aptos-faucet-service = { path = "../vendors/aptos-core-1.7/crates/aptos-faucet/service" } +aptos-faucet-metrics-server = { path = "../vendors/aptos-core-1.7/crates/aptos-faucet/metrics-server" } +aptos-fallible = { path = "../vendors/aptos-core-1.7/crates/fallible" } +aptos-forge = { path = "../vendors/aptos-core-1.7/testsuite/forge" } +aptos-framework = { path = "../vendors/aptos-core-1.7/aptos-move/framework" } +aptos-fuzzer = { path = "../vendors/aptos-core-1.7/testsuite/aptos-fuzzer" } +fuzzer = { path = "../vendors/aptos-core-1.7/testsuite/fuzzer" } +aptos-gas = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-gas" } +aptos-gas-algebra-ext = { path = "../vendors/aptos-core-1.7/aptos-move/gas-algebra-ext" } +aptos-gas-profiling = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-gas-profiling" } +aptos-genesis = { path = "../vendors/aptos-core-1.7/crates/aptos-genesis" } +aptos-github-client = { path = "../vendors/aptos-core-1.7/secure/storage/github" } +aptos-global-constants = { path = "../vendors/aptos-core-1.7/config/global-constants" } +aptos-id-generator = { path = "../vendors/aptos-core-1.7/crates/aptos-id-generator" } +aptos-indexer = { path = "../vendors/aptos-core-1.7/crates/indexer" } +aptos-indexer-grpc-cache-worker = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-cache-worker" } +aptos-indexer-grpc-data-service = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-data-service" } +aptos-indexer-grpc-file-store = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-file-store" } +aptos-indexer-grpc-post-processor = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-post-processor" } +aptos-indexer-grpc-fullnode = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-fullnode" } +aptos-indexer-grpc-utils = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-utils" } +aptos-indexer-grpc-parser = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-parser" } +aptos-indexer-grpc-server-framework = { path = "../vendors/aptos-core-1.7/ecosystem/indexer-grpc/indexer-grpc-server-framework" } +aptos-infallible = { path = "../vendors/aptos-core-1.7/crates/aptos-infallible" } +aptos-inspection-service = { path = "../vendors/aptos-core-1.7/crates/aptos-inspection-service" } +aptos-jellyfish-merkle = { path = "../vendors/aptos-core-1.7/storage/jellyfish-merkle" } +aptos-keygen = { path = "../vendors/aptos-core-1.7/crates/aptos-keygen" } +aptos-language-e2e-tests = { path = "../vendors/aptos-core-1.7/aptos-move/e2e-tests" } +aptos-ledger = { path = "../vendors/aptos-core-1.7/crates/aptos-ledger" } +aptos-log-derive = { path = "../vendors/aptos-core-1.7/crates/aptos-log-derive" } +aptos-logger = { path = "../vendors/aptos-core-1.7/crates/aptos-logger" } +aptos-memory-usage-tracker = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-memory-usage-tracker" } +aptos-mempool = { path = "../vendors/aptos-core-1.7/mempool" } +aptos-mempool-notifications = { path = "../vendors/aptos-core-1.7/state-sync/inter-component/mempool-notifications" } +aptos-memsocket = { path = "../vendors/aptos-core-1.7/network/memsocket" } +aptos-metrics-core = { path = "../vendors/aptos-core-1.7/crates/aptos-metrics-core" } +aptos-move-examples = { path = "../vendors/aptos-core-1.7/aptos-move/move-examples" } +aptos-moving-average = { path = "../vendors/aptos-core-1.7/crates/moving-average" } +aptos-mvhashmap = { path = "../vendors/aptos-core-1.7/aptos-move/mvhashmap" } +aptos-netcore = { path = "../vendors/aptos-core-1.7/network/netcore" } +aptos-network = { path = "../vendors/aptos-core-1.7/network" } +aptos-network-builder = { path = "../vendors/aptos-core-1.7/network/builder" } +aptos-network-checker = { path = "../vendors/aptos-core-1.7/crates/aptos-network-checker" } +aptos-network-discovery = { path = "../vendors/aptos-core-1.7/network/discovery" } +aptos-node = { path = "../vendors/aptos-core-1.7/aptos-node" } +aptos-node-checker = { path = "../vendors/aptos-core-1.7/ecosystem/node-checker" } +aptos-node-identity = { path = "../vendors/aptos-core-1.7/crates/aptos-node-identity" } +aptos-node-resource-metrics = { path = "../vendors/aptos-core-1.7/crates/node-resource-metrics" } +aptos-num-variants = { path = "../vendors/aptos-core-1.7/crates/num-variants" } +aptos-openapi = { path = "../vendors/aptos-core-1.7/crates/aptos-openapi" } +aptos-package-builder = { path = "../vendors/aptos-core-1.7/aptos-move/package-builder" } +aptos-peer-monitoring-service-client = { path = "../vendors/aptos-core-1.7/network/peer-monitoring-service/client" } +aptos-peer-monitoring-service-server = { path = "../vendors/aptos-core-1.7/network/peer-monitoring-service/server" } +aptos-peer-monitoring-service-types = { path = "../vendors/aptos-core-1.7/network/peer-monitoring-service/types" } +aptos-proptest-helpers = { path = "../vendors/aptos-core-1.7/crates/aptos-proptest-helpers" } +aptos-protos = { path = "../vendors/aptos-core-1.7/crates/aptos-protos" } +aptos-proxy = { path = "../vendors/aptos-core-1.7/crates/proxy" } +aptos-push-metrics = { path = "../vendors/aptos-core-1.7/crates/aptos-push-metrics" } +aptos-rate-limiter = { path = "../vendors/aptos-core-1.7/crates/aptos-rate-limiter" } +aptos-release-builder = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-release-builder" } +aptos-resource-viewer = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-resource-viewer" } +aptos-rest-client = { path = "../vendors/aptos-core-1.7/crates/aptos-rest-client" } +aptos-retrier = { path = "../vendors/aptos-core-1.7/crates/aptos-retrier" } +aptos-rocksdb-options = { path = "../vendors/aptos-core-1.7/storage/rocksdb-options" } +aptos-rosetta = { path = "../vendors/aptos-core-1.7/crates/aptos-rosetta" } +aptos-runtimes = { path = "../vendors/aptos-core-1.7/crates/aptos-runtimes" } +aptos-safety-rules = { path = "../vendors/aptos-core-1.7/consensus/safety-rules" } +aptos-schemadb = { path = "../vendors/aptos-core-1.7/storage/schemadb" } +aptos-scratchpad = { path = "../vendors/aptos-core-1.7/storage/scratchpad" } +aptos-sdk = { path = "../vendors/aptos-core-1.7/sdk" } +aptos-sdk-builder = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-sdk-builder" } +aptos-secure-net = { path = "../vendors/aptos-core-1.7/secure/net" } +aptos-secure-storage = { path = "../vendors/aptos-core-1.7/secure/storage" } +aptos-short-hex-str = { path = "../vendors/aptos-core-1.7/crates/short-hex-str" } +aptos-speculative-state-helper = { path = "../vendors/aptos-core-1.7/crates/aptos-speculative-state-helper" } +aptos-state-sync-driver = { path = "../vendors/aptos-core-1.7/state-sync/state-sync-v2/state-sync-driver" } +aptos-state-view = { path = "../vendors/aptos-core-1.7/storage/state-view" } +aptos-storage-interface = { path = "../vendors/aptos-core-1.7/storage/storage-interface" } +aptos-storage-service-client = { path = "../vendors/aptos-core-1.7/state-sync/storage-service/client" } +aptos-storage-service-notifications = { path = "../vendors/aptos-core-1.7/state-sync/inter-component/storage-service-notifications" } +aptos-storage-service-types = { path = "../vendors/aptos-core-1.7/state-sync/storage-service/types" } +aptos-storage-service-server = { path = "../vendors/aptos-core-1.7/state-sync/storage-service/server" } +aptos-telemetry = { path = "../vendors/aptos-core-1.7/crates/aptos-telemetry" } +aptos-telemetry-service = { path = "../vendors/aptos-core-1.7/crates/aptos-telemetry-service" } +aptos-temppath = { path = "../vendors/aptos-core-1.7/crates/aptos-temppath" } +aptos-testcases = { path = "../vendors/aptos-core-1.7/testsuite/testcases" } +aptos-time-service = { path = "../vendors/aptos-core-1.7/crates/aptos-time-service", features = [ "async", ] } -aptos-transaction-emitter-lib = { path = "../third-party/aptos-core-1.7/crates/transaction-emitter-lib" } -aptos-transaction-generator-lib = { path = "../third-party/aptos-core-1.7/crates/transaction-generator-lib" } -aptos-transactional-test-harness = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-transactional-test-harness" } -aptos-types = { path = "../third-party/aptos-core-1.7/types" } -aptos-utils = { path = "../third-party/aptos-core-1.7/aptos-utils" } -aptos-validator-interface = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-validator-interface" } -aptos-vault-client = { path = "../third-party/aptos-core-1.7/secure/storage/vault" } -aptos-vm = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-vm" } -aptos-vm-logging = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-vm-logging" } -aptos-vm-genesis = { path = "../third-party/aptos-core-1.7/aptos-move/vm-genesis" } -aptos-vm-types = { path = "../third-party/aptos-core-1.7/aptos-move/aptos-vm-types" } -aptos-vm-validator = { path = "../third-party/aptos-core-1.7/vm-validator" } -aptos-warp-webserver = { path = "../third-party/aptos-core-1.7/crates/aptos-warp-webserver" } -aptos-writeset-generator = { path = "../third-party/aptos-core-1.7/aptos-move/writeset-transaction-generator" } +aptos-transaction-emitter-lib = { path = "../vendors/aptos-core-1.7/crates/transaction-emitter-lib" } +aptos-transaction-generator-lib = { path = "../vendors/aptos-core-1.7/crates/transaction-generator-lib" } +aptos-transactional-test-harness = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-transactional-test-harness" } +aptos-types = { path = "../vendors/aptos-core-1.7/types" } +aptos-utils = { path = "../vendors/aptos-core-1.7/aptos-utils" } +aptos-validator-interface = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-validator-interface" } +aptos-vault-client = { path = "../vendors/aptos-core-1.7/secure/storage/vault" } +aptos-vm = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-vm" } +aptos-vm-logging = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-vm-logging" } +aptos-vm-genesis = { path = "../vendors/aptos-core-1.7/aptos-move/vm-genesis" } +aptos-vm-types = { path = "../vendors/aptos-core-1.7/aptos-move/aptos-vm-types" } +aptos-vm-validator = { path = "../vendors/aptos-core-1.7/vm-validator" } +aptos-warp-webserver = { path = "../vendors/aptos-core-1.7/crates/aptos-warp-webserver" } +aptos-writeset-generator = { path = "../vendors/aptos-core-1.7/aptos-move/writeset-transaction-generator" } diff --git a/m1/DEBUGGING.md b/m1/DEBUGGING.md new file mode 100644 index 000000000..12385797f --- /dev/null +++ b/m1/DEBUGGING.md @@ -0,0 +1,62 @@ +# Debugging +The easiest way to debug the M1 subnet is to run it locally with... +```shell +./scripts/run.debug.sh +``` + +This will run an `avalanche-network-runner` local cluster with the M1 subnet. The cluster will have the following critical services: +- `0.0.0.0:9650`: the Avalanche node RPC. +- `0.0.0.0:8090`: the gRPC indexer stream. + +Eventually, you should see an output like this to the terminal: +```shell +[node3] ------------inner_build_block 98dbf4c1---- +[node4] ------------inner_build_block 98dbf4c1---- +[node5] ------------inner_build_block 98dbf4c1---- +[node4] -----accept----1--- +[node5] -----accept----1--- +[node3] -----accept----1--- +[node2] -----accept----1--- +[node1] ------------inner_build_block 98dbf4c1---- +[node1] -----accept----1--- +[node1] [2023-11-17T14:34:47Z INFO subnet::vm] submit_transaction length 257 +[node1] ----------notify_block_ready----success------------------ +[node1] ----build_block pool tx count-------1------ +[node1] --------vm_build_block------mo5UvUGgwVEEbCcgeb9JRRXvpr4UeT4yUFufS2R9UA7kXvSNQ--- +[node4] ------------inner_build_block 850f6c4d---- +[node1] ------------inner_build_block 850f6c4d---- +[node1] -----accept----1--- +[node4] -----accept----1--- +[node2] ------------inner_build_block 850f6c4d---- +[node2] -----accept----1--- +[node5] ------------inner_build_block 850f6c4d---- +[node3] ------------inner_build_block 850f6c4d---- +``` + +## `subnet-request-proxy` +Running these without any supporting services will suffice for core protocol debugging. However, you will often want to check the e2e behavior of things like CLI and the JavaScript SDK. For that, you will need to start the `subnet-request-proxy` which is responsible for serving an Aptos-compatible API. + +To start the `subnet-request-proxy` natively on your machine, cd into the `subnet-request-proxy` directory and run: +```shell +npm i +SUBNET_SOCKET_ADDRESS="0.0.0.0:9650" npm run start +``` + +## Indexer Database +In order for the indexer to write to the database listening on port `5432`, you will need to start a local PostgreSQL instance. The easiest way to do this is with Docker: +```shell +docker run --name m1-indexer-db -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres +``` +If you are not running the database, the trailer thread in the M1 subnet will panick. However, this will not affect the rest of the execution. + +# WIP +We are pursuing several improvements to local debugging and testing. + +## Docker Compose +We are working on a Docker Compose file which will allow you to run all services locally without additional setup. + +## Simulated Network Activity Prologue +We are working to provide a script which will simulate the network activity which to provide an option to test against a more realistic network. This will be particularly useful for testing the indexer. + +## Improved Parameterization +We are working on exposing more of the variables through to the runner scripts which network the services, for example, port numbers and the Avalanche node config. diff --git a/m1/INDEXER_FIX.md b/m1/INDEXER_FIX.md new file mode 100644 index 000000000..077c5d91e --- /dev/null +++ b/m1/INDEXER_FIX.md @@ -0,0 +1,13 @@ +# Indexer Fix +See https://github.com/movemntdev/M1/issues/80. + +## Running +@lmonninger has added additional support for running locally via an ANR usage more similar to that used in `timestampvm-rs`. To run locally, you'll need to run the following commands: +```bash +cd m1 +./scripts/tests.debug.sh +``` + +@lmonninger plans to continue to expand this e2e testing suite over the course of the day to provide better automated checks against the indexer and help others debug. + +For now, contributors should attempt the continued streaming failure against the indexer when using grpcurl. \ No newline at end of file diff --git a/m1/JavaScript-client/.eslintignore b/m1/JavaScript-client/.eslintignore deleted file mode 100644 index 4123c09b0..000000000 --- a/m1/JavaScript-client/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -packages/**/node_modules/ -dist/** -**/*.test.ts diff --git a/m1/JavaScript-client/.eslintrc.js b/m1/JavaScript-client/.eslintrc.js deleted file mode 100644 index 86745e95f..000000000 --- a/m1/JavaScript-client/.eslintrc.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = { - env: { - browser: true, - es2021: true, - node: true, - }, - ignorePatterns: ["*.js", "examples/*", "src/indexer/generated/**", "scripts/publish_ans_contract.ts"], - extends: ["airbnb-base", "airbnb-typescript/base", "prettier"], - parser: "@typescript-eslint/parser", - parserOptions: { - tsconfigRootDir: __dirname, - project: ["tsconfig.json"], - ecmaVersion: "latest", - sourceType: "module", - }, - plugins: ["@typescript-eslint"], - rules: { - quotes: ["error", "double"], - "max-len": ["error", 120], - "import/extensions": ["error", "never"], - "max-classes-per-file": ["error", 10], - "import/prefer-default-export": "off", - "object-curly-newline": "off", - "no-use-before-define": "off", - "no-unused-vars": "off", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-unused-vars": ["error"], - }, - settings: { - "import/resolver": { - node: { - extensions: [".js", ".jsx", ".ts", ".tsx"], - }, - }, - }, -}; diff --git a/m1/JavaScript-client/.gitignore b/m1/JavaScript-client/.gitignore deleted file mode 100644 index afdee0d21..000000000 --- a/m1/JavaScript-client/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -.env -.DS_Store -*/**/.DS_Store -npm-debug.log -.npm/ -/coverage -/tmp -node_modules -.idea/ -.history/ -.vscode/ -dist/ -.nyc_output/ -build/ - -# Doc generation output -docs/ \ No newline at end of file diff --git a/m1/JavaScript-client/.npmignore b/m1/JavaScript-client/.npmignore deleted file mode 100644 index 5f7ebc026..000000000 --- a/m1/JavaScript-client/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -coverage -node_modules -.aptos -.env diff --git a/m1/JavaScript-client/.nvmrc b/m1/JavaScript-client/.nvmrc deleted file mode 100644 index 15a541691..000000000 --- a/m1/JavaScript-client/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v16.14.0n diff --git a/m1/JavaScript-client/.prettierignore b/m1/JavaScript-client/.prettierignore deleted file mode 100644 index 9543bddf6..000000000 --- a/m1/JavaScript-client/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -src/generated/* -src/indexer/generated/** diff --git a/m1/JavaScript-client/.versionrc.json b/m1/JavaScript-client/.versionrc.json deleted file mode 100644 index 94df5f411..000000000 --- a/m1/JavaScript-client/.versionrc.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "types": [ - { "type": "feat", "section": "Features" }, - { "type": "fix", "section": "Bug Fixes" }, - { "type": "chore", "hidden": true }, - { "type": "docs", "hidden": true }, - { "type": "style", "hidden": true }, - { "type": "refactor", "hidden": true }, - { "type": "perf", "hidden": true }, - { "type": "test", "hidden": true } - ], - "skip": { - "bump": true, - "commit": true, - "tag": true - }, - "path": ".", - "header": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nNote: This changelog is generated automatically.\n\n" -} diff --git a/m1/JavaScript-client/CHANGELOG.md b/m1/JavaScript-client/CHANGELOG.md deleted file mode 100644 index 6509817cd..000000000 --- a/m1/JavaScript-client/CHANGELOG.md +++ /dev/null @@ -1,225 +0,0 @@ -# Aptos TS SDK Changelog - -All notable changes to the Aptos Node SDK will be captured in this file. This changelog is written by hand for now. It adheres to the format set out by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -**Note:** The Aptos TS SDK does not follow semantic version while we are in active development. Instead, breaking changes will be announced with each devnet cut. Once we launch our mainnet, the SDK will follow semantic versioning closely. - -## Unreleased - -## 1.8.5 (2023-04-29) - -- Add local tests for `AnsClient` -- Add `AptosToken` plugin to support tokenv2 -- Add generic support to input params in move entry functions -- Add signature verification method to AptosAccount. - -## 1.8.4 (2023-04-13) - -- Move `TypeTagParser` from `builder_utils.ts` to `type_tag.ts` -- Update `StructTag.fromString()` to use and relies on TypeTagParser - -## 1.8.3 (2023-04-10) - -- Add `publish-ans-contract` script and pnpm command for tests -- Revert User-Agent header from both `AptosClient` and `IndexerClient` due to a browser error - -## 1.8.2 (2023-04-06) - -- Introduce `AnsClient` class to support ANS (Aptos Names Service) data fetching queries -- Add `User-Agent` header to `AptosClient` and `IndexerClient` queries -- Add Indexer queries to `IndexerClient` - `getAccountCoinsData`, `getAccountTokensCount`, `getAccountTransactionsCount`, `getAccountTransactionsData`, `getCurrentDelegatorBalancesCount`, `getDelegatedStakingActivities`, `getTokensActivitiesCount`, `getTokenData`, `getTokenOwnersData`, `getTopUserTransactions`, `getUserTransactions` -- Add convertion layer to `IndexerClient` queries to handle missing `0x` -- Add validation layer to `IndexerClient` to validate queried account address is in the long format, i.e 66 chars long (0x<64 chars>) -- Change `queryIndexer` function in `IndexerClient` class visibility to public -- Add mint Aptos Name function `mintAptosName()` to `AnsClient` class - -## 1.7.2 (2023-03-13) - -- `CoinClient` and `TokenClient` to use remote ABI instead of local ABIs -- Reorganize SDK files structure for a better readability and maintainability -- Add `getIndexerLedgerInfo` query to `IndexerClient` - -## 1.7.1 (2023-03-02) - -- Fix IndexerClient error parsing using JSON.stringify() to display the error message correctly on the console - -## 1.7.0 (2023-03-01) - -- Add Indexer support. We introduce a new class `IndexerClient` that queries our Indexer to support data shaping fetching and providing users with a seamless experience. -- Introduces a `Provider` class we can initialize and query our blockchain by hiding the underlying implementation (fullnode vs indexer) - -## 1.6.0 (2023-01-20) - -- Add support to Move view functions - -## 1.5.0 (2023-01-05) - -- Export classes from property_map_serde -- User can specify token string property type using "string", "String" or "0x1::string::String" to serde the string token property on-chain -- Use `getAccountResource` to replace `getAccountResources` in `CoinClient#checkBalance`, which can reduce network load. - -## 1.4.0 (2022-11-30) - -- Add missing fields to TokenData class -- Add PropertyMap and PropertyValue type to match on-chain data -- Support token property map deseralizer to read the property map in the original data format. -- Allow `checkBalance` in `CoinClient` to take in a `MaybeHexString` as well as `AptosAccount`, since users might want to check the balance of accounts they don't own (which is generally how you use `AptosAccount`). -- Similar to `checkBalance`, allow `transfer` in `CoinClient` to take in a `MaybeHexString` for the `receiver` argument. -- Add a new `createReceiverIfMissing` argument to `transfer` in `CoinClient`. If set, the `0x1::aptos_account::transfer` function will be called instead of `0x1::coin::transfer`, which will create the account on chain if it doesn't exist instead of failing. - -## 1.3.17 (2022-11-08) - -- Support computing resource account address based off a source address and a seed -- Exported ABI types -- `getAccountModules` and `getAccountResources` now use pagination under the hood. This addresses the issue raised here: https://github.com/aptos-labs/aptos-core/issues/5298. The changes are non-breaking, if you use these functions with an older node that hasn't updated to include the relevant support in its API service, it will still work as it did before. -- To support the above, the generated client has been updated to attach the headers to the response object, as per the changes here: https://github.com/aptos-labs/openapi-typescript-codegen/compare/v0.23.0...aptos-labs:openapi-typescript-codegen:0.24.0?expand=1. Consider this an implementation detail, not a supported part of the SDK interface. -- Add functions to token client support - - direct transfer with opt-in - - burn token by owner - - burn token by creator - - mutate token properties -- Add property map serializer to serialize input to BCS encode - -## 1.3.16 (2022-10-12) - -- Add `estimatePrioritizedGasUnitPrice` to the simulation interface. If set to true, the estimated gas unit price is higher than the original estimate. Therefore, transactions have a higher chance to be executed during congestion period. -- `esitmateGasPrice` now returns `deprioritized_gas_estimate` and `prioritized_gas_estimate` along with `gas_estimate`. `deprioritized_gas_estimate` is a conservative price estimate. Users might end up paying less gas eventually, but the transaction execution is deprioritized by the block chain. On the other hand, `prioritized_gas_estimate` is a higher price esitmate. Transactions need to be executed sooner could use `prioritized_gas_estimate`. - -## 1.3.15 (2022-09-30) - -- **[Breaking Changes]** Following the deprecation notice in the release notes of 1.3.13, the following breaking changes have landed in this release. Please see the notes from last release for information on the new endpoints you must migrate to: - - The `getEventsByEventKey` function has been removed. - - The `key` field in the `Event` struct has been removed. -- Turn on `strict` in tsconfig - -## 1.3.14 (2022-09-20) - -- Enable SDK axios client to carry cookies for both the browser and node environments. -- Added new functions `getBlockByHeight` and `getBlockByVersion`. - -## 1.3.13 (2022-09-15) - -- Increase the default wait time for `waitForTransactionWithResult` to 20s. -- A new function called `getEventsByCreationNumber` has been added, corresponding to the new endpoint on the API. For more information on this change, see the [API changelog](https://github.com/aptos-labs/aptos-core/blob/main/api/doc/CHANGELOG.md) for API version 1.1.0. -- **[Deprecated]** The `getEventsByEventKey` function is now deprecated. In the next release it will be removed entirely. You must migrate to the new function, `getEventsByCreationNumber`, by then. -- Included in the `Event` struct (which is what the events endpoints return) is a new field called `guid`. This is a more easily interpretable representation of an event identifier than the `key` field. See the [API changelog](https://github.com/aptos-labs/aptos-core/blob/main/api/doc/CHANGELOG.md) for an example of the new field. -- **[Deprecated]** The `key` field in the `Event` struct is now deprecated. In the next release it will be removed entirely. You must migrate to using the `guid` field by then. -- Removed NPM dependencies ed25519-hd-key and typescript-memoize. -- Added IIFE bundle that can be served from CDN. No NPM is required to use the SDK in browser environment. - -## 1.3.12 (2022-09-08) - -- Feature to rotate auth key for single signature account - -## 1.3.11 (2022-08-31) - -- Upgraded typescript version from 4.7.4 to 4.8.2, as well as linter package versions. -- **[Breaking Change]** ModuleBundle transaction support is removed. Instead, SDK users should use `AptosClient.publishPackage` to publish Move packages. -- Expose detailed API errors. -- Accept stringified values as transaction payload parameters. - -## 1.3.10 (2022-08-26) - -- Fix the bug in `waitForTransactionWithResult`. When API returns `404`, the function should continue waiting rather than returning early. The reason is that the txn might not be committed promptly. `waitForTransactionWithResult` should either timeout or get an error in such case. - -## 1.3.9 (2022-08-25) - -- **[Breaking Change]** Reimplemented the JSON transaction submission interfaces with BCS. This is a breaking change. `createSigningMessage` is removed. Before the changes, the transaction payloads take string aruguments. But now, Typescript payload arguments have to match the smart contract arugment types. e.g. `number` matches `u8`, `number | bigint` matches `u64` and `u128`, etc. -- **[Breaking Change]** `getTokenBalance` and `getTokenBalanceForAccount` have been renamed to `getToken` and `getTokenForAccount`, since they were never getting just the balance, but the full token. -- Added `CoinClient` to help working with coins. This contains common operations such as `transfer`, `checkBalance`, etc. -- Added `generateSignSubmitWaitForTransaction`, a function that provides a simple way to execute the full end to end transaction submission flow. You may also leverage `generateSignSubmit`, a helper that does the same but without waiting, instead returning teh transaction hash. -- Added `fromDerivePath` to `AptosAccount`. You can use this to create an `AptosAccount` (which is a local representation of an account) using a bip44 path and mnemonics. - -## 1.3.7 (2022-08-17) - -- Add a transaction builder that is able to serialize transaction arguments with remote ABIs. Remote ABIs are fetchable through REST APIs. With the remote ABI transaction builder, developers can build BCS transactions by only providing the native JS values. -- Make all functions that accept `BigInt` parameters accept `BigInt | number` instead. - -## 1.3.6 (2022-08-10) - -- Switch back to representing certain move types (MoveModuleId, MoveStructTag, ScriptFunctionId) as strings, for both requests and responses. This reverts the change made in 1.3.2. See [#2663](https://github.com/aptos-labs/aptos-core/pull/2663) for more. -- Represent certain fields with slightly different snake casing, e.g. `ed25519_signature` now instead of `ed_25519_signature`. -- Add generated types for healthcheck endpoint. -- If the given URL is missing `/v1`, the `AptosClient` constructor will add it for you. You can opt out of this behavior by setting `doNotFixNodeUrl` to true when calling the constructor. - -## 1.3.5 (2022-08-08) - -- Re-expose BCS and items from `transaction_builder/builder` from the root of the module. - -## 1.3.4 (2022-08-07) - -- Downscaled default value for `max_gas`. - -## 1.3.3 (2022-08-05) - -- Update the token clients to submit transactions through BCS interface. The new token client doesn't hex-code "name", "decription" and "uri" any more. String properties are passed and saved just as strings. -- Expose `buildTransactionPayload` from ABI transaction builder. In some scenarios, developers just want to get a TransactionPayload rather than a RawTransaction. - -## 1.3.2 (2022-08-04) - -This special entry does not conform to the format set out by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) as there are noteworthy breaking changes with necessary rationale. Future entries will follow this format. - -This release updates the SDK to work with V1 of the Aptos Node API. There are some key changes between V0 and V1 that you can read about in the [API changelog](https://github.com/aptos-labs/aptos-core/blob/main/api/doc/v1/CHANGELOG.md), refer to the notes for version 1.0.0. Accordingly, this SDK version represents breaking changes compared to 1.2.1. - -- The SDK now communicates by default with the `/v1` path of the API. It will not work correctly with the v0 API. If you provide a path yourself when instantiating a client, make sure you include `/v1`, e.g. http://fullnode.devnet.aptoslabs.com/v1. -- As of this release, the API, API spec, client generated from that spec, SDK wrapper, and examples are all tested together in CI. Previously it was possible for these to be out of sync, or in some cases, they would test against a different deployment entirely, such as devnet. Now we make the guarantee that all these pieces from the same commit work together. Notably this means exactly that; there is no guarantee that the latest version of the SDK will work with a particular Aptos network, such as devnet, except for a network built from the same commit as the SDK. -- The generated client within the SDK is generated using a different tool, [openapi-typescript-codegen](https://www.npmjs.com/package/openapi-typescript-codegen). Most of these changes are transparent to the user, as we continue to wrap the generated client, but some of the generated types are different, which we mention here. -- Token types are no longer exposed from the generated client (under `Types`) as they are no longer part of the API (indeed, they never truly were). Instead you can find these definitions exposed at `TokenTypes`. -- Some functions, such as for getting account resources and events, no longer accept resource types as concatenated strings. For example: - -```tsx -# Before: -const aptosCoin = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"; -# After -const aptosCoin = const aptosCoin = { - address: "0x1", - module: "coin", - name: "CoinStore", - generic_type_params: ["0x1::aptos_coin::AptosCoin"], -}; -``` - -- Similarly, some endpoints no longer return this data as a string, but in a structured format, e.g. `MoveStructTag`. Remember to use something like `lodash.isEqual` to do equality checks with these structs. -- To help work with these different formats, functions for converting between them have been added to `utils`. -- A new function, `waitForTransactionWithResult`, has been added to help wait for a transaction and then get access to the response from the server once the function exits. - -For help with migration, we recommend you see the updated examples under `examples/`, they demonstrate how to deal with some of these changes, such as the more structured responses. We are also available to assist in the [Aptos Discord](https://discord.com/invite/aptoslabs). - -**Deprecation Notice**: On September 1st we will remove the v0 API from the running nodes. As a user of the TS SDK, the best way you can migrate prior to this is by upgrading to version 1.3.2 or higher of the SDK. We will repeatedly remind developers of this upcoming deprecation as we approach that date. - -## 1.3.1 (2022-08-04) - -See release notes for 1.3.2. - -## 1.3.0 (2022-08-03) - -See release notes for 1.3.2. - -## 1.2.1 (2022-07-23) - -**Note:** This entry and earlier do not conform to the format set out by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -### Features - -- Deprecate getTokenBalance api in SDK ([2ec554e](https://github.com/aptos-labs/aptos-core/commit/2ec554e6e40a81cee4e760f6f84ef7362c570240)) -- Memoize chain id in aptos client ([#1589](https://github.com/aptos-labs/aptos-core/issues/1589)) ([4a6453b](https://github.com/aptos-labs/aptos-core/commit/4a6453bf0e620247557854053b661446bff807a7)) -- **Multiagent:** Support multiagent transaction submission ([#1543](https://github.com/aptos-labs/aptos-core/issues/1543)) ([0f0c70e](https://github.com/aptos-labs/aptos-core/commit/0f0c70e8ed2fefa952f0c89b7edb78edc174cb49)) -- Support retrieving token balance for any account ([7f93c21](https://github.com/aptos-labs/aptos-core/commit/7f93c2100f8b8e848461a0b5a395bfb76ade8667)) - -### Bug Fixes - -- Get rid of "natual" calls ([#1678](https://github.com/aptos-labs/aptos-core/issues/1678)) ([54601f7](https://github.com/aptos-labs/aptos-core/commit/54601f79206ea0f8b8b1b0d6599d31832fc4d195)) - -## 1.2.0 (2022-06-28) - -### Features - -- Vector tests for transaction signing ([6210c10](https://github.com/aptos-labs/aptos-core/commit/6210c10d3192fd0417b35709545fae850099e4d4)) -- Add royalty support for NFT tokens ([93a2cd0](https://github.com/aptos-labs/aptos-core/commit/93a2cd0bfd644725ac524f419e94077e0b16343b)) -- Add transaction builder examples ([a710a50](https://github.com/aptos-labs/aptos-core/commit/a710a50e8177258d9c0766762b3c2959fc231259)) -- Support transaction simulation ([93073bf](https://github.com/aptos-labs/aptos-core/commit/93073bf1b508d00cfa1f8bb441ed57085fd08a82)) - -### Bug Fixes - -- Fix a typo, natual now becomes natural ([1b7d295](https://github.com/aptos-labs/aptos-core/commit/1b7d2957b79a5d2821ada0c5096cf43c412e0c2d)), closes [#1526](https://github.com/aptos-labs/aptos-core/issues/1526) -- Fix Javascript example ([5781fee](https://github.com/aptos-labs/aptos-core/commit/5781fee74b8f2b065e7f04c2f76952026860751d)), closes [#1405](https://github.com/aptos-labs/aptos-core/issues/1405) diff --git a/m1/JavaScript-client/CONTRIBUTING.md b/m1/JavaScript-client/CONTRIBUTING.md deleted file mode 100644 index bb0a90406..000000000 --- a/m1/JavaScript-client/CONTRIBUTING.md +++ /dev/null @@ -1,18 +0,0 @@ -# Contribution Guidelines for Typescript SDK - -- Coding Styles - - File names must use Snake case. For example, `aptos_account.ts` . - - Class names must use Pascal case. For example, `class AuthenticationKey` . - - Function and method names must use Camel case. For example, `derivedAddress(): HexString` . - - Constants must use all caps (upper case) words separated by `_`. For example, `MAX_U8_NUMBER` . -- Comments - - Comments are required for new classes and functions. - - Comments should follow the TSDoc standard, [https://tsdoc.org/](https://tsdoc.org/). -- Lints and Formats - - ESlint (eslint) and Prettier (prettier) should be used for code checking and code formatting. Make sure to run `pnpm lint` and `pnpm fmt` after making changes to the code. -- Tests - - Unit tests are required for any non-trivial changes you make. - - The Jest testing framework is used in the repo and we recommend you use it. See Jest: [https://jestjs.io/](https://jestjs.io/). - - Make sure to run `pnpm test` after making changes. -- Commits - - Commit messages follow the [Angular convention](https://www.conventionalcommits.org/en/v1.0.0-beta.4/#summary). diff --git a/m1/JavaScript-client/README.md b/m1/JavaScript-client/README.md deleted file mode 100644 index d5c674e36..000000000 --- a/m1/JavaScript-client/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# SDK for Movement Node API - -## Quickstart - -The public SDK downloaded from [npmjs](https://www.npmjs.com/package/movement-sdk) is compatible with the [movement testnet](https://seed-node1.movementlabs.xyz). To start building, run below command in your project directory: - -```bash -pnpm add movement-sdk -``` diff --git a/m1/JavaScript-client/examples/README.md b/m1/JavaScript-client/examples/README.md deleted file mode 100644 index bfd9ff25d..000000000 --- a/m1/JavaScript-client/examples/README.md +++ /dev/null @@ -1,5 +0,0 @@ -**NOTE**: These examples are tested to work with the [latest SDK published to npmjs](https://www.npmjs.com/package/aptos), not the SDK in the parent directory. Accordingly, these examples should be run against devnet. This is how the examples work by default. - -If you'd like to learn more about how these examples work, please see the following tutorials: -- [Your first transaction](https://aptos.dev/tutorials/your-first-transaction-sdk) -- [Your first NFT](https://aptos.dev/tutorials/your-first-nft-sdk) diff --git a/m1/JavaScript-client/examples/javascript/index.js b/m1/JavaScript-client/examples/javascript/index.js deleted file mode 100644 index 1711417df..000000000 --- a/m1/JavaScript-client/examples/javascript/index.js +++ /dev/null @@ -1,82 +0,0 @@ -require("dotenv").config(); - -const aptos = require("aptos"); - -const NODE_URL = process.env.APTOS_NODE_URL || "https://fullnode.devnet.aptoslabs.com"; -const FAUCET_URL = process.env.APTOS_FAUCET_URL || "https://faucet.devnet.aptoslabs.com"; - -const aptosCoin = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"; - -(async () => { - const client = new aptos.AptosClient(NODE_URL); - const faucetClient = new aptos.FaucetClient(NODE_URL, FAUCET_URL, null); - const tokenClient = new aptos.TokenClient(client); - - const account1 = new aptos.AptosAccount(); - await faucetClient.fundAccount(account1.address(), 100_000_000); - let resources = await client.getAccountResources(account1.address()); - let accountResource = resources.find((r) => r.type === aptosCoin); - console.log(`account1 coins: ${accountResource.data.coin.value}. Should be 100_000_000!`); - - const account2 = new aptos.AptosAccount(); - await faucetClient.fundAccount(account2.address(), 0); - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - console.log(`account2 coins: ${accountResource.data.coin.value}. Should be 0!`); - - const payload = { - type: "entry_function_payload", - function: "0x1::coin::transfer", - type_arguments: ["0x1::aptos_coin::AptosCoin"], - arguments: [account2.address().hex(), 717], - }; - const txnRequest = await client.generateTransaction(account1.address(), payload); - const signedTxn = await client.signTransaction(account1, txnRequest); - const transactionRes = await client.submitTransaction(signedTxn); - await client.waitForTransaction(transactionRes.hash); - - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - console.log(`account2 coins: ${accountResource.data.coin.value}. Should be 717!`); - - const provider = new aptos.Provider(aptos.Network.DEVNET); - console.log("\n=== Checking if indexer devnet chainId same as fullnode chainId ==="); - const indexerLedgerInfo = await provider.getIndexerLedgerInfo(); - const fullNodeChainId = await provider.getChainId(); - - console.log(`\n fullnode chain id is: ${fullNodeChainId}, indexer chain id is: ${indexerLedgerInfo}`); - if (indexerLedgerInfo.ledger_infos[0].chain_id !== fullNodeChainId) { - console.log(`\n fullnode chain id and indexer chain id are not synced, skipping rest of tests`); - return; - } - - console.log("=== Creating account1's NFT Collection and Token ==="); - - const collectionName = "Alice's"; - const tokenName = "Alice's first token"; - - // Create the collection. - // :!:>section_4 - const txnHash1 = await tokenClient.createCollection( - account1, - collectionName, - "Alice's simple collection", - "https://alice.com", - ); // <:!:section_4 - await client.waitForTransaction(txnHash1, { checkSuccess: true }); - - // Create a token in that collection. - // :!:>section_5 - const txnHash2 = await tokenClient.createToken( - account1, - collectionName, - tokenName, - "Alice's simple token", - 1, - "https://aptos.dev/img/nyan.jpeg", - ); // <:!:section_5 - await client.waitForTransaction(txnHash2, { checkSuccess: true }); - - const nfts = await provider.getAccountNFTs(account1.address().hex()); - console.log(`account1 current token ownership: ${nfts.current_token_ownerships[0].amount}. Should be 1`); -})(); diff --git a/m1/JavaScript-client/examples/javascript/package.json b/m1/JavaScript-client/examples/javascript/package.json deleted file mode 100644 index 615f91e60..000000000 --- a/m1/JavaScript-client/examples/javascript/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "js-test", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "node index.js" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "aptos": "latest", - "dotenv": "16.0.2" - } -} diff --git a/m1/JavaScript-client/examples/javascript/pnpm-lock.yaml b/m1/JavaScript-client/examples/javascript/pnpm-lock.yaml deleted file mode 100644 index c853ae473..000000000 --- a/m1/JavaScript-client/examples/javascript/pnpm-lock.yaml +++ /dev/null @@ -1,104 +0,0 @@ -lockfileVersion: '6.0' - -dependencies: - aptos: - specifier: latest - version: 1.7.2 - dotenv: - specifier: 16.0.2 - version: 16.0.2 - -packages: - - /@noble/hashes@1.1.3: - resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} - dev: false - - /@scure/base@1.1.1: - resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} - dev: false - - /@scure/bip39@1.1.0: - resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} - dependencies: - '@noble/hashes': 1.1.3 - '@scure/base': 1.1.1 - dev: false - - /aptos@1.7.2: - resolution: {integrity: sha512-unM7bPbu3UGoVB/EhTvA+QDo8nqb6pDfqttsKwC7nYavQnl4t5dxCoFfIFcbijBtSOTfo4is5ldi4Uz4cY9ESA==} - engines: {node: '>=11.0.0'} - dependencies: - '@noble/hashes': 1.1.3 - '@scure/bip39': 1.1.0 - axios: 0.27.2 - form-data: 4.0.0 - tweetnacl: 1.0.3 - transitivePeerDependencies: - - debug - dev: false - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /dotenv@16.0.2: - resolution: {integrity: sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==} - engines: {node: '>=12'} - dev: false - - /follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /tweetnacl@1.0.3: - resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - dev: false diff --git a/m1/JavaScript-client/examples/typescript-esm/index.ts b/m1/JavaScript-client/examples/typescript-esm/index.ts deleted file mode 100644 index 42d68089f..000000000 --- a/m1/JavaScript-client/examples/typescript-esm/index.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* eslint-disable no-console */ -import { AptosClient, AptosAccount, FaucetClient, BCS, TxnBuilderTypes, Provider, Network, TokenClient } from "aptos"; -import assert from "assert"; - -const NODE_URL = process.env.APTOS_NODE_URL || "https://fullnode.devnet.aptoslabs.com"; -const FAUCET_URL = process.env.APTOS_FAUCET_URL || "https://faucet.devnet.aptoslabs.com"; - -export const aptosCoinStore = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"; - -const { - AccountAddress, - TypeTagStruct, - EntryFunction, - StructTag, - TransactionPayloadEntryFunction, - RawTransaction, - ChainId, -} = TxnBuilderTypes; - -/** - * This code example demonstrates the process of moving test coins from one account to another. - */ -(async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); - const tokenClient = new TokenClient(client); - - // Generates key pair for a new account - const account1 = new AptosAccount(); - await faucetClient.fundAccount(account1.address(), 100_000_000); - let resources = await client.getAccountResources(account1.address()); - let accountResource = resources.find((r: any) => r.type === aptosCoinStore); - let balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 100_000_000); - console.log(`account1 coins: ${balance}. Should be 100_000_000!`); - - const account2 = new AptosAccount(); - // Creates the second account and fund the account with 0 AptosCoin - await faucetClient.fundAccount(account2.address(), 0); - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r: any) => r.type === aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 0); - console.log(`account2 coins: ${balance}. Should be 0!`); - - const token = new TypeTagStruct(StructTag.fromString("0x1::aptos_coin::AptosCoin")); - - // TS SDK support 3 types of transaction payloads: `EntryFunction`, `Script` and `Module`. - // See https://aptos-labs.github.io/ts-sdk-doc/ for the details. - const entryFunctionPayload = new TransactionPayloadEntryFunction( - EntryFunction.natural( - // Fully qualified module name, `AccountAddress::ModuleName` - "0x1::coin", - // Module function - "transfer", - // The coin type to transfer - [token], - // Arguments for function `transfer`: receiver account address and amount to transfer - [BCS.bcsToBytes(AccountAddress.fromHex(account2.address())), BCS.bcsSerializeUint64(717)], - ), - ); - - const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([ - client.getAccount(account1.address()), - client.getChainId(), - ]); - - // See class definiton here - // https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.RawTransaction.html#constructor. - const rawTxn = new RawTransaction( - // Transaction sender account address - AccountAddress.fromHex(account1.address()), - BigInt(sequenceNumber), - entryFunctionPayload, - // Max gas unit to spend - BigInt(10000), - // Gas price per unit - BigInt(100), - // Expiration timestamp. Transaction is discarded if it is not executed within 10 seconds from now. - BigInt(Math.floor(Date.now() / 1000) + 10), - new ChainId(chainId), - ); - - // Sign the raw transaction with account1's private key - const bcsTxn = AptosClient.generateBCSTransaction(account1, rawTxn); - - const transactionRes = await client.submitSignedBCSTransaction(bcsTxn); - - await client.waitForTransaction(transactionRes.hash); - - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r: any) => r.type === aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 717); - console.log(`account2 coins: ${balance}. Should be 717!`); - - const provider = new Provider(Network.DEVNET); - console.log("\n=== Checking if indexer devnet chainId same as fullnode chainId ==="); - const indexerLedgerInfo = await provider.getIndexerLedgerInfo(); - const fullNodeChainId = await provider.getChainId(); - - console.log(`\n fullnode chain id is: ${fullNodeChainId}, indexer chain id is: ${indexerLedgerInfo}`); - if (indexerLedgerInfo.ledger_infos[0].chain_id !== fullNodeChainId) { - console.log(`\n fullnode chain id and indexer chain id are not synced, skipping rest of tests`); - return; - } - - console.log("=== Creating account1's NFT Collection and Token ==="); - - const collectionName = "Alice's"; - const tokenName = "Alice's first token"; - - // Create the collection. - // :!:>section_4 - const txnHash1 = await tokenClient.createCollection( - account1, - collectionName, - "Alice's simple collection", - "https://alice.com", - ); // <:!:section_4 - await client.waitForTransaction(txnHash1, { checkSuccess: true }); - - // Create a token in that collection. - // :!:>section_5 - const txnHash2 = await tokenClient.createToken( - account1, - collectionName, - tokenName, - "Alice's simple token", - 1, - "https://aptos.dev/img/nyan.jpeg", - ); // <:!:section_5 - await client.waitForTransaction(txnHash2, { checkSuccess: true }); - - const nfts = await provider.getAccountNFTs(account1.address().hex()); - console.log(`account1 current token ownership: ${nfts.current_token_ownerships[0].amount}. Should be 1`); -})(); diff --git a/m1/JavaScript-client/examples/typescript-esm/package.json b/m1/JavaScript-client/examples/typescript-esm/package.json deleted file mode 100644 index d4a7b9bfa..000000000 --- a/m1/JavaScript-client/examples/typescript-esm/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "ts-test-esm", - "version": "1.0.0", - "description": "", - "main": "./dist/index.js", - "type": "module", - "scripts": { - "build": "rm -rf dist/* && tsc -p .", - "test": "pnpm build && node ./dist/index.js" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "aptos": "latest" - }, - "devDependencies": { - "typescript": "4.8.2" - } -} diff --git a/m1/JavaScript-client/examples/typescript-esm/pnpm-lock.yaml b/m1/JavaScript-client/examples/typescript-esm/pnpm-lock.yaml deleted file mode 100644 index f0c6b7599..000000000 --- a/m1/JavaScript-client/examples/typescript-esm/pnpm-lock.yaml +++ /dev/null @@ -1,107 +0,0 @@ -lockfileVersion: '6.0' - -dependencies: - aptos: - specifier: latest - version: 1.7.2 - -devDependencies: - typescript: - specifier: 4.8.2 - version: 4.8.2 - -packages: - - /@noble/hashes@1.1.3: - resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} - dev: false - - /@scure/base@1.1.1: - resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} - dev: false - - /@scure/bip39@1.1.0: - resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} - dependencies: - '@noble/hashes': 1.1.3 - '@scure/base': 1.1.1 - dev: false - - /aptos@1.7.2: - resolution: {integrity: sha512-unM7bPbu3UGoVB/EhTvA+QDo8nqb6pDfqttsKwC7nYavQnl4t5dxCoFfIFcbijBtSOTfo4is5ldi4Uz4cY9ESA==} - engines: {node: '>=11.0.0'} - dependencies: - '@noble/hashes': 1.1.3 - '@scure/bip39': 1.1.0 - axios: 0.27.2 - form-data: 4.0.0 - tweetnacl: 1.0.3 - transitivePeerDependencies: - - debug - dev: false - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /tweetnacl@1.0.3: - resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - dev: false - - /typescript@4.8.2: - resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true diff --git a/m1/JavaScript-client/examples/typescript-esm/tsconfig.json b/m1/JavaScript-client/examples/typescript-esm/tsconfig.json deleted file mode 100644 index 4acc21c3b..000000000 --- a/m1/JavaScript-client/examples/typescript-esm/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "allowJs": true, - "declaration": true, - "declarationMap": true, - "esModuleInterop": true, - "experimentalDecorators": true, - "module": "ESNext", - "moduleResolution": "node", - "noImplicitAny": true, - "outDir": "./dist", - "sourceMap": true, - "target": "es2020", - "pretty": true - }, - "include": [ - "*.ts" - ], - "paths": { - "@aptos/*": "../..", - } -} diff --git a/m1/JavaScript-client/examples/typescript/bcs_transaction.ts b/m1/JavaScript-client/examples/typescript/bcs_transaction.ts deleted file mode 100644 index 13f2b21fa..000000000 --- a/m1/JavaScript-client/examples/typescript/bcs_transaction.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* eslint-disable no-console */ - -import dotenv from "dotenv"; -dotenv.config(); - -import { AptosClient, AptosAccount, FaucetClient, BCS, TxnBuilderTypes } from "aptos"; -import { aptosCoinStore } from "./common"; -import assert from "assert"; - -const NODE_URL = process.env.APTOS_NODE_URL || "https://fullnode.devnet.aptoslabs.com"; -const FAUCET_URL = process.env.APTOS_FAUCET_URL || "https://faucet.devnet.aptoslabs.com"; - -const { - AccountAddress, - TypeTagStruct, - EntryFunction, - StructTag, - TransactionPayloadEntryFunction, - RawTransaction, - ChainId, -} = TxnBuilderTypes; - -/** - * This code example demonstrates the process of moving test coins from one account to another. - */ -(async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); - - // Generates key pair for a new account - const account1 = new AptosAccount(); - await faucetClient.fundAccount(account1.address(), 100_000_000); - let resources = await client.getAccountResources(account1.address()); - let accountResource = resources.find((r) => r.type === aptosCoinStore); - let balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 100_000_000); - console.log(`account1 coins: ${balance}. Should be 100000000!`); - - const account2 = new AptosAccount(); - // Creates the second account and fund the account with 0 AptosCoin - await faucetClient.fundAccount(account2.address(), 0); - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 0); - console.log(`account2 coins: ${balance}. Should be 0!`); - - const token = new TypeTagStruct(StructTag.fromString("0x1::aptos_coin::AptosCoin")); - - // TS SDK support 3 types of transaction payloads: `EntryFunction`, `Script` and `Module`. - // See https://aptos-labs.github.io/ts-sdk-doc/ for the details. - const entryFunctionPayload = new TransactionPayloadEntryFunction( - EntryFunction.natural( - // Fully qualified module name, `AccountAddress::ModuleName` - "0x1::coin", - // Module function - "transfer", - // The coin type to transfer - [token], - // Arguments for function `transfer`: receiver account address and amount to transfer - [BCS.bcsToBytes(AccountAddress.fromHex(account2.address())), BCS.bcsSerializeUint64(717)], - ), - ); - - const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([ - client.getAccount(account1.address()), - client.getChainId(), - ]); - - // See class definiton here - // https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.RawTransaction.html#constructor. - const rawTxn = new RawTransaction( - // Transaction sender account address - AccountAddress.fromHex(account1.address()), - BigInt(sequenceNumber), - entryFunctionPayload, - // Max gas unit to spend - BigInt(2000), - // Gas price per unit - BigInt(100), - // Expiration timestamp. Transaction is discarded if it is not executed within 10 seconds from now. - BigInt(Math.floor(Date.now() / 1000) + 10), - new ChainId(chainId), - ); - - // Sign the raw transaction with account1's private key - const bcsTxn = AptosClient.generateBCSTransaction(account1, rawTxn); - - const transactionRes = await client.submitSignedBCSTransaction(bcsTxn); - - await client.waitForTransaction(transactionRes.hash); - - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 717); - console.log(`account2 coins: ${balance}. Should be 717!`); -})(); diff --git a/m1/JavaScript-client/examples/typescript/call_aptos_cli.ts b/m1/JavaScript-client/examples/typescript/call_aptos_cli.ts deleted file mode 100644 index d50ee6e28..000000000 --- a/m1/JavaScript-client/examples/typescript/call_aptos_cli.ts +++ /dev/null @@ -1,28 +0,0 @@ -const ffi = require("ffi-napi"); - -const lib = ffi.Library("../../../../../target/release/libaptos", { - run_aptos_sync: ["char *", ["string"]], // run the aptos CLI synchronously - run_aptos_async: ["char *", ["string"]], // run the aptos CLI asynchronously - free_cstring: ["void", ["char *"]], // free the return pointer memory allocated by the aptos CLI -}); - -const args_run_local_testnet = ["aptos", "node", "run-local-testnet", "--with-faucet"]; -const args_aptos_info = ["aptos", "info"]; - -(async () => { - console.log("Running aptos CLI from Typescript"); - const aptos_info = lib.run_aptos_sync(args_aptos_info.join(" ")); - const run_local_testnet = lib.run_aptos_async(args_run_local_testnet.join(" ")); - try { - console.log(`Aptos Info: ${aptos_info.readCString()}`); - console.log(`Run Local Testnet: ${run_local_testnet.readCString()}`); - } catch (error) { - console.error(error); - } finally { - // free the string pointer memory allocated by the aptos CLI - lib.free_cstring(aptos_info); - lib.free_cstring(run_local_testnet); - } - - console.log("Finish aptos CLI"); -})(); diff --git a/m1/JavaScript-client/examples/typescript/common.ts b/m1/JavaScript-client/examples/typescript/common.ts deleted file mode 100644 index e11898af6..000000000 --- a/m1/JavaScript-client/examples/typescript/common.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -//:!:>section_1 -export const NODE_URL = process.env.APTOS_NODE_URL || "https://fullnode.devnet.aptoslabs.com"; -export const FAUCET_URL = process.env.APTOS_FAUCET_URL || "https://faucet.devnet.aptoslabs.com"; -//<:!:section_1 - -export const aptosCoinStore = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"; diff --git a/m1/JavaScript-client/examples/typescript/multisig_account.ts b/m1/JavaScript-client/examples/typescript/multisig_account.ts deleted file mode 100644 index 81518f979..000000000 --- a/m1/JavaScript-client/examples/typescript/multisig_account.ts +++ /dev/null @@ -1,210 +0,0 @@ -/* eslint-disable no-console */ - -import dotenv from "dotenv"; -dotenv.config(); - -import { AptosClient, AptosAccount, FaucetClient, BCS, TxnBuilderTypes } from "aptos"; -import { sha3_256 as sha3Hash } from "@noble/hashes/sha3"; -import { aptosCoinStore, FAUCET_URL, NODE_URL } from "./common"; -import assert from "assert"; - -const { AccountAddress, EntryFunction, MultiSig, MultiSigTransactionPayload, TransactionPayloadMultisig } = - TxnBuilderTypes; - -/** - * This code example demonstrates the new multisig account module and transaction execution flow. - */ -(async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); - - // Create and fund 3 accounts that will be the owners of the multisig account. - const owner1 = new AptosAccount(); - const owner2 = new AptosAccount(); - const owner3 = new AptosAccount(); - const owner4 = new AptosAccount(); - await faucetClient.fundAccount(owner1.address(), 100_000_000); - await faucetClient.fundAccount(owner2.address(), 100_000_000); - await faucetClient.fundAccount(owner3.address(), 100_000_000); - - // Step 1: Setup a 2-of-3 multisig account - // =========================================================================================== - const createMultisig = await client.generateTransaction(owner1.address(), { - function: "0x1::multisig_account::create_with_owners", - type_arguments: [], - arguments: [[owner2.address().hex(), owner3.address().hex()], 2, ["Shaka"], [BCS.bcsSerializeStr("Bruh")]], - }); - await client.generateSignSubmitWaitForTransaction(owner1, createMultisig.payload); - // Find the multisig account address. - let ownedMultisigAccounts = await client.getAccountResource( - owner1.address(), - "0x1::multisig_account::OwnedMultisigAccounts", - ); - const multisigAddress = (ownedMultisigAccounts?.data as any).multisig_accounts[0]; - assert((await getSignatureThreshold(client, multisigAddress)) == 2); - assert((await getNumberOfOwners(client, multisigAddress)) == 3); - - // Fund the multisig account for transfers. - await faucetClient.fundAccount(multisigAddress, 100_000_000); - - // Step 2: Create a multisig transaction to send 1_000_000 coins to an account. - // We'll be including the full payload to be stored on chain. - // =========================================================================================== - const recipient = new AptosAccount(); - const transferTxPayload = new MultiSigTransactionPayload( - EntryFunction.natural( - "0x1::aptos_account", - "transfer", - [], - [BCS.bcsToBytes(AccountAddress.fromHex(recipient.address())), BCS.bcsSerializeUint64(1_000_000)], - ), - ); - const multisigTxExecution = new TransactionPayloadMultisig( - new MultiSig(AccountAddress.fromHex(multisigAddress), transferTxPayload), - ); - const [simulationResp] = await client.simulateTransaction( - owner2, - await client.generateRawTransaction(owner2.address(), multisigTxExecution), - ); - assert(simulationResp.success); - - // Create the multisig tx on chain. - const createMultisigTx = await client.generateTransaction(owner2.address(), { - function: "0x1::multisig_account::create_transaction", - type_arguments: [], - arguments: [multisigAddress, BCS.bcsToBytes(transferTxPayload)], - }); - await client.generateSignSubmitWaitForTransaction(owner2, createMultisigTx.payload); - - // Owner 1 rejects but owner 3 approves. - await rejectAndApprove(client, owner1, owner3, multisigAddress, 1); - - // Owner 2 can now execute the transactions as it already has 2 approvals (from owners 2 and 3). - await client.generateSignSubmitWaitForTransaction(owner2, multisigTxExecution); - let accountResource = await client.getAccountResource(recipient.address(), aptosCoinStore); - let balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 1_000_000); - - // Step 3: Create another multisig transaction to send 1_000_000 coins but use payload hash instead. - // =========================================================================================== - const transferTxPayloadHash = sha3Hash.create(); - transferTxPayloadHash.update(BCS.bcsToBytes(transferTxPayload)); - const createMultisigTxWithHash = await client.generateTransaction(owner2.address(), { - function: "0x1::multisig_account::create_transaction_with_hash", - type_arguments: [], - arguments: [multisigAddress, transferTxPayloadHash.digest()], - }); - await client.generateSignSubmitWaitForTransaction(owner2, createMultisigTxWithHash.payload); - await rejectAndApprove(client, owner1, owner3, multisigAddress, 2); - - const multisigTxExecution2 = new TransactionPayloadMultisig( - new MultiSig(AccountAddress.fromHex(multisigAddress), transferTxPayload), - ); - await client.generateSignSubmitWaitForTransaction(owner2, multisigTxExecution2); - accountResource = await client.getAccountResource(recipient.address(), aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 2_000_000); - - // Step 4: Create 2 multisig transactions: one to add a new owner and another one to remove it. - // =========================================================================================== - const owner_4 = new AptosAccount(); - const addOwnerPayload = new MultiSigTransactionPayload( - EntryFunction.natural( - "0x1::multisig_account", - "add_owner", - [], - [BCS.bcsToBytes(AccountAddress.fromHex(owner_4.address()))], - ), - ); - const addOwnerTx = await client.generateTransaction(owner2.address(), { - function: "0x1::multisig_account::create_transaction", - type_arguments: [], - arguments: [multisigAddress, BCS.bcsToBytes(addOwnerPayload)], - }); - await client.generateSignSubmitWaitForTransaction(owner2, addOwnerTx.payload); - await rejectAndApprove(client, owner1, owner3, multisigAddress, 3); - await client.generateSignSubmitWaitForTransaction( - owner2, - new TransactionPayloadMultisig(new MultiSig(AccountAddress.fromHex(multisigAddress))), - ); - // The multisig account should now have 4 owners. - assert((await getNumberOfOwners(client, multisigAddress)) == 4); - - const removeOwnerPayload = new MultiSigTransactionPayload( - EntryFunction.natural( - "0x1::multisig_account", - "remove_owner", - [], - [BCS.bcsToBytes(AccountAddress.fromHex(owner_4.address()))], - ), - ); - const removeOwnerTx = await client.generateTransaction(owner2.address(), { - function: "0x1::multisig_account::create_transaction", - type_arguments: [], - arguments: [multisigAddress, BCS.bcsToBytes(removeOwnerPayload)], - }); - await client.generateSignSubmitWaitForTransaction(owner2, removeOwnerTx.payload); - await rejectAndApprove(client, owner1, owner3, multisigAddress, 4); - await client.generateSignSubmitWaitForTransaction( - owner2, - new TransactionPayloadMultisig(new MultiSig(AccountAddress.fromHex(multisigAddress))), - ); - // The multisig account should now have 3 owners. - assert((await getNumberOfOwners(client, multisigAddress)) == 3); - - // Step 5: Create a multisig transactions to change the signature threshold to 3-of-3. - // =========================================================================================== - const changeSigThresholdPayload = new MultiSigTransactionPayload( - EntryFunction.natural("0x1::multisig_account", "update_signatures_required", [], [BCS.bcsSerializeUint64(3)]), - ); - const changeSigThresholdTx = await client.generateTransaction(owner2.address(), { - function: "0x1::multisig_account::create_transaction", - type_arguments: [], - arguments: [multisigAddress, BCS.bcsToBytes(changeSigThresholdPayload)], - }); - await client.generateSignSubmitWaitForTransaction(owner2, changeSigThresholdTx.payload); - await rejectAndApprove(client, owner1, owner3, multisigAddress, 5); - await client.generateSignSubmitWaitForTransaction( - owner2, - new TransactionPayloadMultisig(new MultiSig(AccountAddress.fromHex(multisigAddress))), - ); - // The multisig account should now be 3-of-3. - assert((await getSignatureThreshold(client, multisigAddress)) == 3); -})(); - -const rejectAndApprove = async ( - client: AptosClient, - owner1: AptosAccount, - owner2: AptosAccount, - multisigAddress: string, - transactionId: number, -) => { - let rejectTx = await client.generateTransaction(owner1.address(), { - function: "0x1::multisig_account::reject_transaction", - type_arguments: [], - arguments: [multisigAddress, transactionId], - }); - await client.generateSignSubmitWaitForTransaction(owner1, rejectTx.payload); - let approveTx = await client.generateTransaction(owner2.address(), { - function: "0x1::multisig_account::approve_transaction", - type_arguments: [], - arguments: [multisigAddress, transactionId], - }); - await client.generateSignSubmitWaitForTransaction(owner2, approveTx.payload); -}; - -const getNumberOfOwners = async (client: AptosClient, multisigAddress: string): Promise => { - const multisigAccountResource = await client.getAccountResource( - multisigAddress, - "0x1::multisig_account::MultisigAccount", - ); - return Number((multisigAccountResource.data as any).owners.length); -}; - -const getSignatureThreshold = async (client: AptosClient, multisigAddress: string): Promise => { - const multisigAccountResource = await client.getAccountResource( - multisigAddress, - "0x1::multisig_account::MultisigAccount", - ); - return Number((multisigAccountResource.data as any).num_signatures_required); -}; diff --git a/m1/JavaScript-client/examples/typescript/multisig_transaction.ts b/m1/JavaScript-client/examples/typescript/multisig_transaction.ts deleted file mode 100644 index 17a59b937..000000000 --- a/m1/JavaScript-client/examples/typescript/multisig_transaction.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* eslint-disable no-console */ - -import dotenv from "dotenv"; -dotenv.config(); - -import { AptosClient, AptosAccount, FaucetClient, BCS, TransactionBuilderMultiEd25519, TxnBuilderTypes } from "aptos"; -import { aptosCoinStore } from "./common"; -import assert from "assert"; - -const NODE_URL = process.env.APTOS_NODE_URL || "https://fullnode.devnet.aptoslabs.com"; -const FAUCET_URL = process.env.APTOS_FAUCET_URL || "https://faucet.devnet.aptoslabs.com"; - -/** - * This code example demonstrates the process of moving test coins from one multisig - * account to a single signature account. - */ -(async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); - - // Genereate 3 key pairs and account instances - const account1 = new AptosAccount(); - const account2 = new AptosAccount(); - const account3 = new AptosAccount(); - - // Create a 2 out of 3 MultiEd25519PublicKey. '2 out of 3' means for a multisig transaction - // to be executed, at least 2 accounts must have signed the transaction. - // See https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.MultiEd25519PublicKey.html#constructor - const multiSigPublicKey = new TxnBuilderTypes.MultiEd25519PublicKey( - [ - new TxnBuilderTypes.Ed25519PublicKey(account1.signingKey.publicKey), - new TxnBuilderTypes.Ed25519PublicKey(account2.signingKey.publicKey), - new TxnBuilderTypes.Ed25519PublicKey(account3.signingKey.publicKey), - ], - // Threshold - 2, - ); - - // Each Aptos account stores an auth key. Initial account address can be derived from auth key. - // See https://aptos.dev/concepts/accounts for more details. - const authKey = TxnBuilderTypes.AuthenticationKey.fromMultiEd25519PublicKey(multiSigPublicKey); - - // Derive the multisig account address and fund the address with 5000 AptosCoin. - const mutisigAccountAddress = authKey.derivedAddress(); - await faucetClient.fundAccount(mutisigAccountAddress, 100_000_000); - - let resources = await client.getAccountResources(mutisigAccountAddress); - let accountResource = resources.find((r) => r.type === aptosCoinStore); - let balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 100_000_000); - console.log(`multisig account coins: ${balance}. Should be 100000000!`); - - const account4 = new AptosAccount(); - // Creates a receiver account and fund the account with 0 AptosCoin - await faucetClient.fundAccount(account4.address(), 0); - resources = await client.getAccountResources(account4.address()); - accountResource = resources.find((r) => r.type === aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 0); - console.log(`account4 coins: ${balance}. Should be 0!`); - - const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin")); - - // TS SDK support 3 types of transaction payloads: `EntryFunction`, `Script` and `Module`. - // See https://aptos-labs.github.io/ts-sdk-doc/ for the details. - const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction( - TxnBuilderTypes.EntryFunction.natural( - // Fully qualified module name, `AccountAddress::ModuleName` - "0x1::coin", - // Module function - "transfer", - // The coin type to transfer - [token], - // Arguments for function `transfer`: receiver account address and amount to transfer - [BCS.bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(account4.address())), BCS.bcsSerializeUint64(123)], - ), - ); - - const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([ - client.getAccount(mutisigAccountAddress), - client.getChainId(), - ]); - - // See class definiton here - // https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.RawTransaction.html#constructor. - const rawTxn = new TxnBuilderTypes.RawTransaction( - // Transaction sender account address - TxnBuilderTypes.AccountAddress.fromHex(mutisigAccountAddress), - BigInt(sequenceNumber), - entryFunctionPayload, - // Max gas unit to spend - BigInt(10000), - // Gas price per unit - BigInt(100), - // Expiration timestamp. Transaction is discarded if it is not executed within 10 seconds from now. - BigInt(Math.floor(Date.now() / 1000) + 10), - new TxnBuilderTypes.ChainId(chainId), - ); - - // account1 and account3 sign the transaction - const txnBuilder = new TransactionBuilderMultiEd25519((signingMessage: TxnBuilderTypes.SigningMessage) => { - const sigHexStr1 = account1.signBuffer(signingMessage); - const sigHexStr3 = account3.signBuffer(signingMessage); - - // Bitmap masks which public key has signed transaction. - // See https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.MultiEd25519Signature.html#createBitmap - const bitmap = TxnBuilderTypes.MultiEd25519Signature.createBitmap([0, 2]); - - // See https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.MultiEd25519Signature.html#constructor - const muliEd25519Sig = new TxnBuilderTypes.MultiEd25519Signature( - [ - new TxnBuilderTypes.Ed25519Signature(sigHexStr1.toUint8Array()), - new TxnBuilderTypes.Ed25519Signature(sigHexStr3.toUint8Array()), - ], - bitmap, - ); - - return muliEd25519Sig; - }, multiSigPublicKey); - - const bcsTxn = txnBuilder.sign(rawTxn); - const transactionRes = await client.submitSignedBCSTransaction(bcsTxn); - - await client.waitForTransaction(transactionRes.hash); - - resources = await client.getAccountResources(mutisigAccountAddress); - accountResource = resources.find((r) => r.type === aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - console.log(`multisig account coins: ${balance}.`); - - resources = await client.getAccountResources(account4.address()); - accountResource = resources.find((r) => r.type === aptosCoinStore); - balance = parseInt((accountResource?.data as any).coin.value); - assert(balance === 123); - console.log(`account4 coins: ${balance}. Should be 123!`); -})(); diff --git a/m1/JavaScript-client/examples/typescript/package.json b/m1/JavaScript-client/examples/typescript/package.json deleted file mode 100644 index 46e700c5d..000000000 --- a/m1/JavaScript-client/examples/typescript/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "ts-test", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "bcs_transaction": "ts-node bcs_transaction.ts", - "multisig_account": "ts-node multisig_account.ts", - "multisig_transaction": "ts-node multisig_transaction.ts", - "simple_nft": "ts-node simple_nft.ts", - "transfer_coin": "ts-node transfer_coin.ts", - "test": "run-s bcs_transaction multisig_transaction simple_nft transfer_coin", - "your_coin": "ts-node your_coin.ts", - "call_aptos_cli": "ts-node call_aptos_cli.ts" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "aptos": "latest", - "dotenv": "16.0.1", - "ffi-napi": "^4.0.3", - "ref-array-di": "^1.2.2" - }, - "devDependencies": { - "@types/ffi-napi": "^4.0.7", - "@types/node": "18.6.2", - "npm-run-all": "4.1.5", - "ts-node": "10.9.1", - "typescript": "4.8.2" - } -} diff --git a/m1/JavaScript-client/examples/typescript/pnpm-lock.yaml b/m1/JavaScript-client/examples/typescript/pnpm-lock.yaml deleted file mode 100644 index 71fba9cfa..000000000 --- a/m1/JavaScript-client/examples/typescript/pnpm-lock.yaml +++ /dev/null @@ -1,1076 +0,0 @@ -lockfileVersion: '6.0' - -dependencies: - aptos: - specifier: latest - version: 1.8.4 - dotenv: - specifier: 16.0.1 - version: 16.0.1 - ffi-napi: - specifier: ^4.0.3 - version: 4.0.3 - ref-array-di: - specifier: ^1.2.2 - version: 1.2.2 - -devDependencies: - '@types/ffi-napi': - specifier: ^4.0.7 - version: 4.0.7 - '@types/node': - specifier: 18.6.2 - version: 18.6.2 - npm-run-all: - specifier: 4.1.5 - version: 4.1.5 - ts-node: - specifier: 10.9.1 - version: 10.9.1(@types/node@18.6.2)(typescript@4.8.2) - typescript: - specifier: 4.8.2 - version: 4.8.2 - -packages: - - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - - /@jridgewell/resolve-uri@3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true - - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@noble/hashes@1.1.3: - resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} - dev: false - - /@scure/base@1.1.1: - resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} - dev: false - - /@scure/bip39@1.1.0: - resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} - dependencies: - '@noble/hashes': 1.1.3 - '@scure/base': 1.1.1 - dev: false - - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.3: - resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} - dev: true - - /@types/ffi-napi@4.0.7: - resolution: {integrity: sha512-2CvLfgxCUUSj7qVab6/uFLyVpgVd2gEV4H/TQEHHn6kZTV8iTesz9uo0bckhwzsh71atutOv8P3JmvRX2ZvpZg==} - dependencies: - '@types/node': 18.6.2 - '@types/ref-napi': 3.0.7 - '@types/ref-struct-di': 1.1.9 - dev: true - - /@types/node@18.6.2: - resolution: {integrity: sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ==} - dev: true - - /@types/ref-napi@3.0.7: - resolution: {integrity: sha512-CzPwr36VkezSpaJGdQX/UrczMSDsDgsWQQFEfQkS799Ft7n/s183a53lsql7RwVq+Ik4yLEgI84pRnLC0XXRlA==} - dependencies: - '@types/node': 18.6.2 - dev: true - - /@types/ref-struct-di@1.1.9: - resolution: {integrity: sha512-B1FsB1BhG1VLx0+IqBaAPXEPH0wCOb+Glaaw/i+nRUwDKFtSqWOziGnTRw05RyrBbrDsMiM0tVWmaujrs016Sw==} - dependencies: - '@types/ref-napi': 3.0.7 - dev: true - - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - - /aptos@1.8.4: - resolution: {integrity: sha512-LWasWcz8+SMj4nCGQzB8kC0P/b2PRraUSjIQmeQH6jJ4O2WqS4MASzQZdk3vkG+i5O2dgLRgDK2QUZaxHqfydQ==} - engines: {node: '>=11.0.0'} - dependencies: - '@noble/hashes': 1.1.3 - '@scure/bip39': 1.1.0 - axios: 0.27.2 - form-data: 4.0.0 - tweetnacl: 1.0.3 - transitivePeerDependencies: - - debug - dev: false - - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /array-index@1.0.0: - resolution: {integrity: sha512-jesyNbBkLQgGZMSwA1FanaFjalb1mZUGxGeUEkSDidzgrbjBGhvizJkaItdhkt8eIHFOJC7nDsrXk+BaehTdRw==} - dependencies: - debug: 2.6.9 - es6-symbol: 3.1.3 - transitivePeerDependencies: - - supports-color - dev: false - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} - engines: {node: '>= 0.4'} - dev: true - - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.0 - dev: true - - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.1 - shebang-command: 1.2.0 - which: 1.3.1 - dev: true - - /d@1.0.1: - resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} - dependencies: - es5-ext: 0.10.62 - type: 1.2.0 - dev: false - - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: false - - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: false - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: false - - /define-properties@1.2.0: - resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} - engines: {node: '>= 0.4'} - dependencies: - has-property-descriptors: 1.0.0 - object-keys: 1.1.1 - dev: true - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /dotenv@16.0.1: - resolution: {integrity: sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==} - engines: {node: '>=12'} - dev: false - - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es-abstract@1.21.1: - resolution: {integrity: sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 - es-to-primitive: 1.2.1 - function-bind: 1.1.1 - function.prototype.name: 1.1.5 - get-intrinsic: 1.2.0 - get-symbol-description: 1.0.0 - globalthis: 1.0.3 - gopd: 1.0.1 - has: 1.0.3 - has-property-descriptors: 1.0.0 - has-proto: 1.0.1 - has-symbols: 1.0.3 - internal-slot: 1.0.5 - is-array-buffer: 3.0.2 - is-callable: 1.2.7 - is-negative-zero: 2.0.2 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - is-string: 1.0.7 - is-typed-array: 1.1.10 - is-weakref: 1.0.2 - object-inspect: 1.12.3 - object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.4.3 - safe-regex-test: 1.0.0 - string.prototype.trimend: 1.0.6 - string.prototype.trimstart: 1.0.6 - typed-array-length: 1.0.4 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.9 - dev: true - - /es-set-tostringtag@2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 - has-tostringtag: 1.0.0 - dev: true - - /es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 - dev: true - - /es5-ext@0.10.62: - resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} - engines: {node: '>=0.10'} - requiresBuild: true - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - next-tick: 1.1.0 - dev: false - - /es6-iterator@2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-symbol: 3.1.3 - dev: false - - /es6-symbol@3.1.3: - resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} - dependencies: - d: 1.0.1 - ext: 1.7.0 - dev: false - - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - /ext@1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - dependencies: - type: 2.7.2 - dev: false - - /ffi-napi@4.0.3: - resolution: {integrity: sha512-PMdLCIvDY9mS32RxZ0XGb95sonPRal8aqRhLbeEtWKZTe2A87qRFG9HjOhvG8EX2UmQw5XNRMIOT+1MYlWmdeg==} - engines: {node: '>=10'} - requiresBuild: true - dependencies: - debug: 4.3.4 - get-uv-event-loop-napi-h: 1.0.6 - node-addon-api: 3.2.1 - node-gyp-build: 4.6.0 - ref-napi: 3.0.3 - ref-struct-di: 1.1.1 - transitivePeerDependencies: - - supports-color - dev: false - - /follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - dev: true - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true - - /function.prototype.name@1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.1 - functions-have-names: 1.2.3 - dev: true - - /functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true - - /get-intrinsic@1.2.0: - resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.3 - dev: true - - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - dev: true - - /get-symbol-from-current-process-h@1.0.2: - resolution: {integrity: sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==} - dev: false - - /get-uv-event-loop-napi-h@1.0.6: - resolution: {integrity: sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==} - dependencies: - get-symbol-from-current-process-h: 1.0.2 - dev: false - - /globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} - engines: {node: '>= 0.4'} - dependencies: - define-properties: 1.2.0 - dev: true - - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - dependencies: - get-intrinsic: 1.2.0 - dev: true - - /graceful-fs@4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true - - /has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true - - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true - - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} - dependencies: - get-intrinsic: 1.2.0 - dev: true - - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - dev: true - - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - dev: true - - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - dev: true - - /hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true - - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 - side-channel: 1.0.4 - dev: true - - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - is-typed-array: 1.1.10 - dev: true - - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - dependencies: - has-bigints: 1.0.2 - dev: true - - /is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true - - /is-core-module@2.11.0: - resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} - dependencies: - has: 1.0.3 - dev: true - - /is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} - engines: {node: '>= 0.4'} - dev: true - - /is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /is-typed-array@1.1.10: - resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - dev: true - - /is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - dependencies: - call-bind: 1.0.2 - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - /json-parse-better-errors@1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - dev: true - - /load-json-file@4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} - dependencies: - graceful-fs: 4.2.10 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 - dev: true - - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /memorystream@0.3.1: - resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} - engines: {node: '>= 0.10.0'} - dev: true - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: false - - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: false - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: false - - /next-tick@1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - dev: false - - /nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: true - - /node-addon-api@3.2.1: - resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - dev: false - - /node-gyp-build@4.6.0: - resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} - hasBin: true - dev: false - - /normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.1 - semver: 5.7.1 - validate-npm-package-license: 3.0.4 - dev: true - - /npm-run-all@4.1.5: - resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} - engines: {node: '>= 4'} - hasBin: true - dependencies: - ansi-styles: 3.2.1 - chalk: 2.4.2 - cross-spawn: 6.0.5 - memorystream: 0.3.1 - minimatch: 3.1.2 - pidtree: 0.3.1 - read-pkg: 3.0.0 - shell-quote: 1.8.0 - string.prototype.padend: 3.1.4 - dev: true - - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - dev: true - - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true - - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true - - /parse-json@4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - dev: true - - /path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: true - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true - - /path-type@3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: true - - /pidtree@0.3.1: - resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} - engines: {node: '>=0.10'} - hasBin: true - dev: true - - /pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - dev: true - - /read-pkg@3.0.0: - resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} - engines: {node: '>=4'} - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - dev: true - - /ref-array-di@1.2.2: - resolution: {integrity: sha512-jhCmhqWa7kvCVrWhR/d7RemkppqPUdxEil1CtTtm7FkZV8LcHHCK3Or9GinUiFP5WY3k0djUkMvhBhx49Jb2iA==} - dependencies: - array-index: 1.0.0 - debug: 3.2.7 - transitivePeerDependencies: - - supports-color - dev: false - - /ref-napi@3.0.3: - resolution: {integrity: sha512-LiMq/XDGcgodTYOMppikEtJelWsKQERbLQsYm0IOOnzhwE9xYZC7x8txNnFC9wJNOkPferQI4vD4ZkC0mDyrOA==} - engines: {node: '>= 10.0'} - requiresBuild: true - dependencies: - debug: 4.3.4 - get-symbol-from-current-process-h: 1.0.2 - node-addon-api: 3.2.1 - node-gyp-build: 4.6.0 - transitivePeerDependencies: - - supports-color - dev: false - - /ref-struct-di@1.1.1: - resolution: {integrity: sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==} - dependencies: - debug: 3.2.7 - transitivePeerDependencies: - - supports-color - dev: false - - /regexp.prototype.flags@1.4.3: - resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - functions-have-names: 1.2.3 - dev: true - - /resolve@1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true - dependencies: - is-core-module: 2.11.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - is-regex: 1.1.4 - dev: true - - /semver@5.7.1: - resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true - dev: true - - /shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 - dev: true - - /shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: true - - /shell-quote@1.8.0: - resolution: {integrity: sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==} - dev: true - - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - object-inspect: 1.12.3 - dev: true - - /spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.13 - dev: true - - /spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true - - /spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.13 - dev: true - - /spdx-license-ids@3.0.13: - resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} - dev: true - - /string.prototype.padend@3.1.4: - resolution: {integrity: sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.1 - dev: true - - /string.prototype.trimend@1.0.6: - resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.1 - dev: true - - /string.prototype.trimstart@1.0.6: - resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.1 - dev: true - - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true - - /ts-node@10.9.1(@types/node@18.6.2)(typescript@4.8.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.3 - '@types/node': 18.6.2 - acorn: 8.8.2 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.8.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /tweetnacl@1.0.3: - resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - dev: false - - /type@1.2.0: - resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: false - - /type@2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - dev: false - - /typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} - dependencies: - call-bind: 1.0.2 - for-each: 0.3.3 - is-typed-array: 1.1.10 - dev: true - - /typescript@4.8.2: - resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - dependencies: - call-bind: 1.0.2 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - dev: true - - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - - /validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - dev: true - - /which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 - dev: true - - /which-typed-array@1.1.9: - resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - is-typed-array: 1.1.10 - dev: true - - /which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true diff --git a/m1/JavaScript-client/examples/typescript/simple_nft.ts b/m1/JavaScript-client/examples/typescript/simple_nft.ts deleted file mode 100644 index 1ef576290..000000000 --- a/m1/JavaScript-client/examples/typescript/simple_nft.ts +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable no-console */ - -import dotenv from "dotenv"; -dotenv.config(); - -import { AptosClient, AptosAccount, FaucetClient, TokenClient, CoinClient, Network, Provider } from "aptos"; -import { NODE_URL, FAUCET_URL } from "./common"; - -(async () => { - // Create API and faucet clients. - // :!:>section_1a - const client = new AptosClient(NODE_URL); - const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); // <:!:section_1a - - // Create client for working with the token module. - // :!:>section_1b - const tokenClient = new TokenClient(client); // <:!:section_1b - - // Create a coin client for checking account balances. - const coinClient = new CoinClient(client); - - // Create accounts. - // :!:>section_2 - const alice = new AptosAccount(); - const bob = new AptosAccount(); // <:!:section_2 - - console.log("=== network ==="); - console.log(NODE_URL); - - // Print out account addresses. - console.log("=== Addresses ==="); - console.log(`Alice: ${alice.address()}`); - console.log(`Bob: ${bob.address()}`); - console.log(""); - - // Fund accounts. - // :!:>section_3 - await faucetClient.fundAccount(alice.address(), 100_000_000); - await faucetClient.fundAccount(bob.address(), 100_000_000); // <:!:section_3 - - console.log("=== Initial Coin Balances ==="); - console.log(`Alice: ${await coinClient.checkBalance(alice)}`); - console.log(`Bob: ${await coinClient.checkBalance(bob)}`); - console.log(""); - - console.log("=== Creating Collection and Token ==="); - - const collectionName = "Alice's"; - const tokenName = "Alice's first token"; - const tokenPropertyVersion = 0; - - const tokenId = { - token_data_id: { - creator: alice.address().hex(), - collection: collectionName, - name: tokenName, - }, - property_version: `${tokenPropertyVersion}`, - }; - - // Create the collection. - // :!:>section_4 - const txnHash1 = await tokenClient.createCollection( - alice, - collectionName, - "Alice's simple collection", - "https://alice.com", - ); // <:!:section_4 - await client.waitForTransaction(txnHash1, { checkSuccess: true }); - - // Create a token in that collection. - // :!:>section_5 - const txnHash2 = await tokenClient.createToken( - alice, - collectionName, - tokenName, - "Alice's simple token", - 1, - "https://aptos.dev/img/nyan.jpeg", - ); // <:!:section_5 - await client.waitForTransaction(txnHash2, { checkSuccess: true }); - - // Print the collection data. - // :!:>section_6 - const collectionData = await tokenClient.getCollectionData(alice.address(), collectionName); - console.log(`Alice's collection: ${JSON.stringify(collectionData, null, 4)}`); // <:!:section_6 - - // Get the token balance. - // :!:>section_7 - const aliceBalance1 = await tokenClient.getToken( - alice.address(), - collectionName, - tokenName, - `${tokenPropertyVersion}`, - ); - console.log(`Alice's token balance: ${aliceBalance1["amount"]}`); // <:!:section_7 - - // Get the token data. - // :!:>section_8 - const tokenData = await tokenClient.getTokenData(alice.address(), collectionName, tokenName); - console.log(`Alice's token data: ${JSON.stringify(tokenData, null, 4)}`); // <:!:section_8 - - // Alice offers one token to Bob. - console.log("\n=== Transferring the token to Bob ==="); - // :!:>section_9 - const txnHash3 = await tokenClient.offerToken( - alice, - bob.address(), - alice.address(), - collectionName, - tokenName, - 1, - tokenPropertyVersion, - ); // <:!:section_9 - await client.waitForTransaction(txnHash3, { checkSuccess: true }); - - // Bob claims the token Alice offered him. - // :!:>section_10 - const txnHash4 = await tokenClient.claimToken( - bob, - alice.address(), - alice.address(), - collectionName, - tokenName, - tokenPropertyVersion, - ); // <:!:section_10 - await client.waitForTransaction(txnHash4, { checkSuccess: true }); - - // Print their balances. - const aliceBalance2 = await tokenClient.getToken( - alice.address(), - collectionName, - tokenName, - `${tokenPropertyVersion}`, - ); - const bobBalance2 = await tokenClient.getTokenForAccount(bob.address(), tokenId); - console.log(`Alice's token balance: ${aliceBalance2["amount"]}`); - console.log(`Bob's token balance: ${bobBalance2["amount"]}`); - - console.log("\n=== Transferring the token back to Alice using MultiAgent ==="); - // :!:>section_11 - let txnHash5 = await tokenClient.directTransferToken( - bob, - alice, - alice.address(), - collectionName, - tokenName, - 1, - tokenPropertyVersion, - ); // <:!:section_11 - await client.waitForTransaction(txnHash5, { checkSuccess: true }); - - // Print out their balances one last time. - const aliceBalance3 = await tokenClient.getToken( - alice.address(), - collectionName, - tokenName, - `${tokenPropertyVersion}`, - ); - const bobBalance3 = await tokenClient.getTokenForAccount(bob.address(), tokenId); - console.log(`Alice's token balance: ${aliceBalance3["amount"]}`); - console.log(`Bob's token balance: ${bobBalance3["amount"]}`); - - const provider = new Provider(Network.DEVNET); - console.log("\n=== Checking if indexer devnet chainId same as fullnode chainId ==="); - const indexerLedgerInfo = await provider.getIndexerLedgerInfo(); - const fullNodeChainId = await provider.getChainId(); - - console.log( - `\n fullnode chain id is: ${fullNodeChainId}, indexer chain id is: ${indexerLedgerInfo.ledger_infos[0].chain_id}`, - ); - - if (indexerLedgerInfo.ledger_infos[0].chain_id !== fullNodeChainId) { - console.log(`\n fullnode chain id and indexer chain id are not synced, skipping rest of tests`); - return; - } - - console.log("\n=== Getting Alices's NFTs ==="); - const aliceNfts = await provider.getAccountNFTs(alice.address().hex()); - console.log(`Alice current token ownership: ${aliceNfts.current_token_ownerships[0].amount}. Should be 1`); - - console.log("\n=== Getting Bob's NFTs ==="); - const bobNfts = await provider.getAccountNFTs(bob.address().hex()); - console.log(`Bob current token ownership: ${bobNfts.current_token_ownerships.length}. Should be 0`); -})(); diff --git a/m1/JavaScript-client/examples/typescript/transfer_coin.ts b/m1/JavaScript-client/examples/typescript/transfer_coin.ts deleted file mode 100644 index 20fb899dc..000000000 --- a/m1/JavaScript-client/examples/typescript/transfer_coin.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable no-console */ - -import dotenv from "dotenv"; -dotenv.config(); - -import { AptosClient, AptosAccount, CoinClient, FaucetClient } from "aptos"; -import { NODE_URL, FAUCET_URL } from "./common"; - -(async () => { - // Create API and faucet clients. - // :!:>section_1 - const client = new AptosClient(NODE_URL); - const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); // <:!:section_1 - - // Create client for working with the coin module. - // :!:>section_1a - const coinClient = new CoinClient(client); // <:!:section_1a - - // Create accounts. - // :!:>section_2 - const alice = new AptosAccount(); - const bob = new AptosAccount(); // <:!:section_2 - - // Print out account addresses. - console.log("=== Addresses ==="); - console.log(`Alice: ${alice.address()}`); - console.log(`Bob: ${bob.address()}`); - console.log(""); - - // Fund accounts. - // :!:>section_3 - await faucetClient.fundAccount(alice.address(), 100_000_000); - await faucetClient.fundAccount(bob.address(), 0); // <:!:section_3 - - // Print out initial balances. - console.log("=== Initial Balances ==="); - // :!:>section_4 - console.log(`Alice: ${await coinClient.checkBalance(alice)}`); - console.log(`Bob: ${await coinClient.checkBalance(bob)}`); // <:!:section_4 - console.log(""); - - // Have Alice send Bob some AptosCoins. - // :!:>section_5 - let txnHash = await coinClient.transfer(alice, bob, 1_000, { gasUnitPrice: BigInt(100) }); // <:!:section_5 - // :!:>section_6a - await client.waitForTransaction(txnHash); // <:!:section_6a - - // Print out intermediate balances. - console.log("=== Intermediate Balances ==="); - console.log(`Alice: ${await coinClient.checkBalance(alice)}`); - console.log(`Bob: ${await coinClient.checkBalance(bob)}`); - console.log(""); - - // Have Alice send Bob some more AptosCoins. - txnHash = await coinClient.transfer(alice, bob, 1_000, { gasUnitPrice: BigInt(100) }); - // :!:>section_6b - await client.waitForTransaction(txnHash, { checkSuccess: true }); // <:!:section_6b - - // Print out final balances. - console.log("=== Final Balances ==="); - console.log(`Alice: ${await coinClient.checkBalance(alice)}`); - console.log(`Bob: ${await coinClient.checkBalance(bob)}`); - console.log(""); -})(); diff --git a/m1/JavaScript-client/examples/typescript/tsconfig.json b/m1/JavaScript-client/examples/typescript/tsconfig.json deleted file mode 100644 index b6381f2d6..000000000 --- a/m1/JavaScript-client/examples/typescript/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "allowJs": true, - "declaration": true, - "declarationMap": true, - "esModuleInterop": true, - "experimentalDecorators": true, - "module": "commonjs", - "noImplicitAny": true, - "outDir": "./dist", - "sourceMap": true, - "target": "es2020", - "pretty": true - }, - "include": [ - "src", - "*.ts" - ], - "paths": { - "@aptos/*": "../..", - } -} diff --git a/m1/JavaScript-client/examples/typescript/your_coin.ts b/m1/JavaScript-client/examples/typescript/your_coin.ts deleted file mode 100644 index 9460b863d..000000000 --- a/m1/JavaScript-client/examples/typescript/your_coin.ts +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import assert from "assert"; -import fs from "fs"; -import path from "path"; -import { NODE_URL, FAUCET_URL } from "./common"; -import { AptosAccount, AptosClient, TxnBuilderTypes, MaybeHexString, HexString, FaucetClient } from "aptos"; -/** - This example depends on the MoonCoin.move module having already been published to the destination blockchain. - - One method to do so is to use the CLI: - * Acquire the Aptos CLI, see https://aptos.dev/cli-tools/aptos-cli-tool/install-aptos-cli - * `pnpm your_coin ~/aptos-core/aptos-move/move-examples/moon_coin`. - * Open another terminal and `aptos move compile --package-dir ~/aptos-core/aptos-move/move-examples/moon_coin --save-metadata --named-addresses MoonCoin=`. - * Return to the first terminal and press enter. - */ - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -class CoinClient extends AptosClient { - constructor() { - super(NODE_URL); - } - - /** Register the receiver account to receive transfers for the new coin. */ - async registerCoin(coinTypeAddress: HexString, coinReceiver: AptosAccount): Promise { - const rawTxn = await this.generateTransaction(coinReceiver.address(), { - function: "0x1::managed_coin::register", - type_arguments: [`${coinTypeAddress.hex()}::moon_coin::MoonCoin`], - arguments: [], - }); - - const bcsTxn = await this.signTransaction(coinReceiver, rawTxn); - const pendingTxn = await this.submitTransaction(bcsTxn); - - return pendingTxn.hash; - } - - /** Mints the newly created coin to a specified receiver address */ - async transferCoin(sender: AptosAccount, receiverAddress: HexString, amount: number | bigint): Promise { - const rawTxn = await this.generateTransaction(sender.address(), { - function: "0x1::aptos_account::transfer_coins", - type_arguments: [`${sender.address()}::moon_coin::MoonCoin`], - arguments: [receiverAddress.hex(), amount], - }); - - const bcsTxn = await this.signTransaction(sender, rawTxn); - const pendingTxn = await this.submitTransaction(bcsTxn); - - return pendingTxn.hash; - } - - /** Mints the newly created coin to a specified receiver address */ - async mintCoin(minter: AptosAccount, receiverAddress: HexString, amount: number | bigint): Promise { - const rawTxn = await this.generateTransaction(minter.address(), { - function: "0x1::managed_coin::mint", - type_arguments: [`${minter.address()}::moon_coin::MoonCoin`], - arguments: [receiverAddress.hex(), amount], - }); - - const bcsTxn = await this.signTransaction(minter, rawTxn); - const pendingTxn = await this.submitTransaction(bcsTxn); - - return pendingTxn.hash; - } - - /** Return the balance of the newly created coin */ - async getBalance(accountAddress: MaybeHexString, coinTypeAddress: HexString): Promise { - try { - const resource = await this.getAccountResource( - accountAddress, - `0x1::coin::CoinStore<${coinTypeAddress.hex()}::moon_coin::MoonCoin>`, - ); - - return parseInt((resource.data as any)["coin"]["value"]); - } catch (_) { - return 0; - } - } -} - -/** run our demo! */ -async function main() { - assert(process.argv.length == 3, "Expecting an argument that points to the moon_coin directory."); - - const client = new CoinClient(); - const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); - - // Create two accounts, Alice and Bob, and fund Alice but not Bob - const alice = new AptosAccount(); - const bob = new AptosAccount(); - - console.log("\n=== Addresses ==="); - console.log(`Alice: ${alice.address()}`); - console.log(`Bob: ${bob.address()}`); - - await faucetClient.fundAccount(alice.address(), 100_000_000); - await faucetClient.fundAccount(bob.address(), 100_000_000); - - await new Promise((resolve) => { - readline.question("Update the module with Alice's address, compile, and press enter.", () => { - resolve(); - readline.close(); - }); - }); - - // :!:>publish - const modulePath = process.argv[2]; - const packageMetadata = fs.readFileSync(path.join(modulePath, "build", "Examples", "package-metadata.bcs")); - const moduleData = fs.readFileSync(path.join(modulePath, "build", "Examples", "bytecode_modules", "moon_coin.mv")); - - console.log("Publishing MoonCoin package."); - let txnHash = await client.publishPackage(alice, new HexString(packageMetadata.toString("hex")).toUint8Array(), [ - new TxnBuilderTypes.Module(new HexString(moduleData.toString("hex")).toUint8Array()), - ]); - await client.waitForTransaction(txnHash, { checkSuccess: true }); // <:!:publish - - console.log(`Bob's initial MoonCoin balance: ${await client.getBalance(bob.address(), alice.address())}.`); - console.log("Alice mints herself some of the new coin."); - txnHash = await client.registerCoin(alice.address(), alice); - await client.waitForTransaction(txnHash, { checkSuccess: true }); - txnHash = await client.mintCoin(alice, alice.address(), 100); - await client.waitForTransaction(txnHash, { checkSuccess: true }); - - console.log("Alice transfers the newly minted coins to Bob."); - txnHash = await client.transferCoin(alice, bob.address(), 100); - await client.waitForTransaction(txnHash, { checkSuccess: true }); - console.log(`Bob's updated MoonCoin balance: ${await client.getBalance(bob.address(), alice.address())}.`); -} - -if (require.main === module) { - main().then((resp) => console.log(resp)); -} diff --git a/m1/JavaScript-client/jest.config.js b/m1/JavaScript-client/jest.config.js deleted file mode 100644 index 885816192..000000000 --- a/m1/JavaScript-client/jest.config.js +++ /dev/null @@ -1,20 +0,0 @@ -/** @type {import("ts-jest/dist/types").InitialOptionsTsJest} */ -module.exports = { - preset: "ts-jest", - moduleNameMapper: { - "^(\\.{1,2}/.*)\\.js$": "$1", - }, - testEnvironment: "node", - coveragePathIgnorePatterns: ["generated/*", "./aptos_types/*", "utils/memoize-decorator.ts", "utils/hd-key.ts"], - testPathIgnorePatterns: ["dist/*"], - collectCoverage: true, - setupFiles: ["dotenv/config"], - coverageThreshold: { - global: { - branches: 50, // 90, - functions: 50, // 95, - lines: 50, // 95, - statements: 50, // 95, - }, - }, -}; diff --git a/m1/JavaScript-client/package.json b/m1/JavaScript-client/package.json deleted file mode 100644 index 12af11d1b..000000000 --- a/m1/JavaScript-client/package.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "movement-sdk", - "description": "Movement SDK", - "packageManager": "pnpm@8.3.1", - "license": "Apache-2.0", - "engines": { - "node": ">=11.0.0" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "import": "./dist/index.mjs", - "require": "./dist/index.js", - "types": "./dist/index.d.ts" - } - }, - "scripts": { - "prepack": "pnpm build", - "build": "pnpm build:clean && pnpm _build:node && pnpm _build:browser", - "build:clean": "rm -rf dist", - "_build:browser": "tsup --platform browser --format iife --global-name movementSDK --minify", - "_build:node": "tsup --format cjs,esm --dts", - "lint": "eslint \"**/*.ts\"", - "test": "pnpm run publish-ans-contract && jest", - "_fmt": "prettier 'scripts/**/*.ts' 'src/**/*.ts' 'examples/**/*.js' 'examples/**/*.ts' '.eslintrc.js'", - "fmt": "pnpm _fmt --write", - "fmt:check": "pnpm _fmt --check", - "cov:clean": "rm -rf coverage", - "generate-client": "openapi -i ../../../api/doc/spec.yaml -o ./src/generated -c axios --name AptosGeneratedClient --exportSchemas true", - "checked-publish": "scripts/checked_publish.sh", - "generate-ts-docs": "scripts/generate_ts_docs.sh", - "indexer-codegen": "graphql-codegen --config ./src/indexer/codegen.yml", - "publish-ans-contract": "ts-node ./scripts/publish_ans_contract.ts" - }, - "repository": { - "type": "git", - "url": "https://github.com/movemntdev/movement-subnet" - }, - "homepage": "https://docs.movementlabs.xyz/", - "author": "movementdev", - "keywords": [ - "Movement", - "Movement Labs", - "Move" - ], - "dependencies": { - "@noble/hashes": "1.1.3", - "@scure/bip39": "1.1.0", - "axios": "0.27.2", - "form-data": "4.0.0", - "tweetnacl": "1.0.3" - }, - "devDependencies": { - "@graphql-codegen/cli": "^2.13.5", - "@graphql-codegen/import-types-preset": "^2.2.3", - "@graphql-codegen/typescript": "^2.7.3", - "@graphql-codegen/typescript-graphql-request": "^4.5.8", - "@graphql-codegen/typescript-operations": "^2.5.3", - "@types/jest": "28.1.8", - "@types/node": "18.6.2", - "@typescript-eslint/eslint-plugin": "5.36.2", - "@typescript-eslint/parser": "5.36.2", - "dotenv": "16.0.2", - "eslint": "8.23.0", - "eslint-config-airbnb-base": "15.0.0", - "eslint-config-airbnb-typescript": "17.0.0", - "eslint-config-prettier": "8.5.0", - "eslint-plugin-import": "2.26.0", - "graphql": "^16.5.0", - "graphql-request": "^5.1.0", - "jest": "28.1.3", - "openapi-typescript-codegen": "https://github.com/aptos-labs/openapi-typescript-codegen/releases/download/v0.24.0-p1/openapi-typescript-codegen-v0.24.0-p1.tgz", - "prettier": "2.6.2", - "ts-jest": "28.0.8", - "ts-loader": "9.3.1", - "ts-node": "10.9.1", - "tsup": "6.2.3", - "typedoc": "^0.23.20", - "typescript": "4.8.2" - }, - "version": "1.0.3" -} diff --git a/m1/JavaScript-client/pnpm-lock.yaml b/m1/JavaScript-client/pnpm-lock.yaml deleted file mode 100644 index 7efcb0398..000000000 --- a/m1/JavaScript-client/pnpm-lock.yaml +++ /dev/null @@ -1,6984 +0,0 @@ -lockfileVersion: '6.0' - -dependencies: - '@noble/hashes': - specifier: 1.1.3 - version: 1.1.3 - '@scure/bip39': - specifier: 1.1.0 - version: 1.1.0 - axios: - specifier: 0.27.2 - version: 0.27.2 - form-data: - specifier: 4.0.0 - version: 4.0.0 - tweetnacl: - specifier: 1.0.3 - version: 1.0.3 - -devDependencies: - '@graphql-codegen/cli': - specifier: ^2.13.5 - version: 2.16.5(@babel/core@7.19.6)(@types/node@18.6.2)(graphql@16.6.0)(typescript@4.8.2) - '@graphql-codegen/import-types-preset': - specifier: ^2.2.3 - version: 2.2.6(graphql@16.6.0) - '@graphql-codegen/typescript': - specifier: ^2.7.3 - version: 2.8.8(graphql@16.6.0) - '@graphql-codegen/typescript-graphql-request': - specifier: ^4.5.8 - version: 4.5.8(graphql-request@5.1.0)(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/typescript-operations': - specifier: ^2.5.3 - version: 2.5.13(graphql@16.6.0) - '@types/jest': - specifier: 28.1.8 - version: 28.1.8 - '@types/node': - specifier: 18.6.2 - version: 18.6.2 - '@typescript-eslint/eslint-plugin': - specifier: 5.36.2 - version: 5.36.2(@typescript-eslint/parser@5.36.2)(eslint@8.23.0)(typescript@4.8.2) - '@typescript-eslint/parser': - specifier: 5.36.2 - version: 5.36.2(eslint@8.23.0)(typescript@4.8.2) - dotenv: - specifier: 16.0.2 - version: 16.0.2 - eslint: - specifier: 8.23.0 - version: 8.23.0 - eslint-config-airbnb-base: - specifier: 15.0.0 - version: 15.0.0(eslint-plugin-import@2.26.0)(eslint@8.23.0) - eslint-config-airbnb-typescript: - specifier: 17.0.0 - version: 17.0.0(@typescript-eslint/eslint-plugin@5.36.2)(@typescript-eslint/parser@5.36.2)(eslint-plugin-import@2.26.0)(eslint@8.23.0) - eslint-config-prettier: - specifier: 8.5.0 - version: 8.5.0(eslint@8.23.0) - eslint-plugin-import: - specifier: 2.26.0 - version: 2.26.0(@typescript-eslint/parser@5.36.2)(eslint@8.23.0) - graphql: - specifier: ^16.5.0 - version: 16.6.0 - graphql-request: - specifier: ^5.1.0 - version: 5.1.0(graphql@16.6.0) - jest: - specifier: 28.1.3 - version: 28.1.3(@types/node@18.6.2)(ts-node@10.9.1) - openapi-typescript-codegen: - specifier: https://github.com/aptos-labs/openapi-typescript-codegen/releases/download/v0.24.0-p1/openapi-typescript-codegen-v0.24.0-p1.tgz - version: '@github.com/aptos-labs/openapi-typescript-codegen/releases/download/v0.24.0-p1/openapi-typescript-codegen-v0.24.0-p1.tgz' - prettier: - specifier: 2.6.2 - version: 2.6.2 - ts-jest: - specifier: 28.0.8 - version: 28.0.8(@babel/core@7.19.6)(esbuild@0.15.13)(jest@28.1.3)(typescript@4.8.2) - ts-loader: - specifier: 9.3.1 - version: 9.3.1(typescript@4.8.2)(webpack@5.80.0) - ts-node: - specifier: 10.9.1 - version: 10.9.1(@types/node@18.6.2)(typescript@4.8.2) - tsup: - specifier: 6.2.3 - version: 6.2.3(ts-node@10.9.1)(typescript@4.8.2) - typedoc: - specifier: ^0.23.20 - version: 0.23.20(typescript@4.8.2) - typescript: - specifier: 4.8.2 - version: 4.8.2 - -packages: - - /@ampproject/remapping@2.2.0: - resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.1.1 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@apidevtools/json-schema-ref-parser@9.0.9: - resolution: {integrity: sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==} - dependencies: - '@jsdevtools/ono': 7.1.3 - '@types/json-schema': 7.0.11 - call-me-maybe: 1.0.2 - js-yaml: 4.1.0 - dev: true - - /@ardatan/relay-compiler@12.0.0(graphql@16.6.0): - resolution: {integrity: sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==} - hasBin: true - peerDependencies: - graphql: '*' - dependencies: - '@babel/core': 7.19.6 - '@babel/generator': 7.20.14 - '@babel/parser': 7.20.15 - '@babel/runtime': 7.20.13 - '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 - babel-preset-fbjs: 3.4.0(@babel/core@7.19.6) - chalk: 4.1.2 - fb-watchman: 2.0.2 - fbjs: 3.0.4 - glob: 7.2.3 - graphql: 16.6.0 - immutable: 3.7.6 - invariant: 2.2.4 - nullthrows: 1.1.1 - relay-runtime: 12.0.0 - signedsource: 1.0.0 - yargs: 15.4.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@ardatan/sync-fetch@0.0.1: - resolution: {integrity: sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA==} - engines: {node: '>=14'} - dependencies: - node-fetch: 2.6.9 - transitivePeerDependencies: - - encoding - dev: true - - /@babel/code-frame@7.18.6: - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - dev: true - - /@babel/compat-data@7.20.1: - resolution: {integrity: sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/compat-data@7.20.14: - resolution: {integrity: sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core@7.19.6: - resolution: {integrity: sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.1 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.19.6) - '@babel/helper-module-transforms': 7.19.6 - '@babel/helpers': 7.20.1 - '@babel/parser': 7.20.1 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.0 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/generator@7.20.1: - resolution: {integrity: sha512-u1dMdBUmA7Z0rBB97xh8pIhviK7oItYOkjbsCxTWMknyvbQRBwX7/gn4JXurRdirWMFh+ZtYARqkA6ydogVZpg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - '@jridgewell/gen-mapping': 0.3.2 - jsesc: 2.5.2 - dev: true - - /@babel/generator@7.20.14: - resolution: {integrity: sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.7 - '@jridgewell/gen-mapping': 0.3.2 - jsesc: 2.5.2 - dev: true - - /@babel/helper-annotate-as-pure@7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.7 - dev: true - - /@babel/helper-compilation-targets@7.20.0(@babel/core@7.19.6): - resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.20.1 - '@babel/core': 7.19.6 - '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.4 - semver: 6.3.0 - dev: true - - /@babel/helper-compilation-targets@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.20.14 - '@babel/core': 7.19.6 - '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.4 - lru-cache: 5.1.1 - semver: 6.3.0 - dev: true - - /@babel/helper-create-class-features-plugin@7.20.12(@babel/core@7.19.6): - resolution: {integrity: sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-member-expression-to-functions': 7.20.7 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-replace-supers': 7.20.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/helper-split-export-declaration': 7.18.6 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-environment-visitor@7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-function-name@7.19.0: - resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.18.10 - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-hoist-variables@7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-member-expression-to-functions@7.20.7: - resolution: {integrity: sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.7 - dev: true - - /@babel/helper-module-imports@7.18.6: - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-module-transforms@7.19.6: - resolution: {integrity: sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.19.4 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-module-transforms@7.20.11: - resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.20.7 - '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-optimise-call-expression@7.18.6: - resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.7 - dev: true - - /@babel/helper-plugin-utils@7.19.0: - resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-plugin-utils@7.20.2: - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-replace-supers@7.20.7: - resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-member-expression-to-functions': 7.20.7 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/template': 7.20.7 - '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-simple-access@7.19.4: - resolution: {integrity: sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-simple-access@7.20.2: - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.7 - dev: true - - /@babel/helper-skip-transparent-expression-wrappers@7.20.0: - resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.7 - dev: true - - /@babel/helper-split-export-declaration@7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-string-parser@7.19.4: - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option@7.18.6: - resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helpers@7.20.1: - resolution: {integrity: sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/highlight@7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - - /@babel/parser@7.20.1: - resolution: {integrity: sha512-hp0AYxaZJhxULfM1zyp7Wgr+pSUKBcP3M+PHnSzWGdXOzg/kHWIgiUWARvubhUKGOEw3xqY4x+lyZ9ytBVcELw==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/parser@7.20.15: - resolution: {integrity: sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.20.7 - dev: true - - /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-create-class-features-plugin': 7.20.12(@babel/core@7.19.6) - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.20.14 - '@babel/core': 7.19.6 - '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.19.6) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-transform-parameters': 7.20.7(@babel/core@7.19.6) - dev: true - - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.19.6): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.19.6): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.19.6): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-flow@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.19.6): - resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.19.6): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.19.6): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.19.6): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.19.6): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.19.6): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.19.6): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.19.6): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.19.6): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.19.6): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.19.6): - resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-arrow-functions@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-block-scoping@7.20.15(@babel/core@7.19.6): - resolution: {integrity: sha512-Vv4DMZ6MiNOhu/LdaZsT/bsLRxgL94d269Mv4R/9sp6+Mp++X/JqypZYypJXLlM4mlL352/Egzbzr98iABH1CA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-classes@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.19.6) - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.20.7 - '@babel/helper-split-export-declaration': 7.18.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-computed-properties@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/template': 7.20.7 - dev: true - - /@babel/plugin-transform-destructuring@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-flow-strip-types@7.19.0(@babel/core@7.19.6): - resolution: {integrity: sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.19.6) - dev: true - - /@babel/plugin-transform-for-of@7.18.8(@babel/core@7.19.6): - resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.19.6): - resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.19.6) - '@babel/helper-function-name': 7.19.0 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-literals@7.18.9(@babel/core@7.19.6): - resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-modules-commonjs@7.20.11(@babel/core@7.19.6): - resolution: {integrity: sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-module-transforms': 7.20.11 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.20.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-parameters@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-react-jsx@7.20.13(@babel/core@7.19.6): - resolution: {integrity: sha512-MmTZx/bkUrfJhhYAYt3Urjm+h8DQGrPrnKQ94jLo7NLuOU+T89a7IByhKmrb8SKhrIYIQ0FN0CHMbnFRen4qNw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.19.6) - '@babel/types': 7.20.7 - dev: true - - /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.19.6): - resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-spread@7.20.7(@babel/core@7.19.6): - resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - dev: true - - /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.19.6): - resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/runtime@7.20.13: - resolution: {integrity: sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.11 - dev: true - - /@babel/template@7.18.10: - resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.1 - '@babel/types': 7.20.0 - dev: true - - /@babel/template@7.20.7: - resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.15 - '@babel/types': 7.20.7 - dev: true - - /@babel/traverse@7.20.1: - resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.1 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.1 - '@babel/types': 7.20.0 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/traverse@7.20.13: - resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.14 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.15 - '@babel/types': 7.20.7 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types@7.20.0: - resolution: {integrity: sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.19.4 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - - /@babel/types@7.20.7: - resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.19.4 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - - /@esbuild/android-arm@0.15.13: - resolution: {integrity: sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.15.13: - resolution: {integrity: sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@eslint/eslintrc@1.3.3: - resolution: {integrity: sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.4.0 - globals: 13.17.0 - ignore: 5.2.0 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@graphql-codegen/add@3.2.3(graphql@16.6.0): - resolution: {integrity: sha512-sQOnWpMko4JLeykwyjFTxnhqjd/3NOG2OyMuvK76Wnnwh8DRrNf2VEs2kmSvLl7MndMlOj7Kh5U154dVcvhmKQ==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.4.1 - dev: true - - /@graphql-codegen/cli@2.16.5(@babel/core@7.19.6)(@types/node@18.6.2)(graphql@16.6.0)(typescript@4.8.2): - resolution: {integrity: sha512-XYPIp+q7fB0xAGSAoRykiTe4oY80VU+z+dw5nuv4mLY0+pv7+pa2C6Nwhdw7a65lXOhFviBApWCCZeqd54SMnA==} - hasBin: true - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@babel/generator': 7.20.14 - '@babel/template': 7.20.7 - '@babel/types': 7.20.7 - '@graphql-codegen/core': 2.6.8(graphql@16.6.0) - '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.6.0) - '@graphql-tools/apollo-engine-loader': 7.3.23(@types/node@18.6.2)(graphql@16.6.0) - '@graphql-tools/code-file-loader': 7.3.18(@babel/core@7.19.6)(graphql@16.6.0) - '@graphql-tools/git-loader': 7.2.17(@babel/core@7.19.6)(graphql@16.6.0) - '@graphql-tools/github-loader': 7.3.24(@babel/core@7.19.6)(@types/node@18.6.2)(graphql@16.6.0) - '@graphql-tools/graphql-file-loader': 7.5.15(graphql@16.6.0) - '@graphql-tools/json-file-loader': 7.4.16(graphql@16.6.0) - '@graphql-tools/load': 7.8.11(graphql@16.6.0) - '@graphql-tools/prisma-loader': 7.2.60(@types/node@18.6.2)(graphql@16.6.0) - '@graphql-tools/url-loader': 7.17.9(@types/node@18.6.2)(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@whatwg-node/fetch': 0.6.6(@types/node@18.6.2) - chalk: 4.1.2 - chokidar: 3.5.3 - cosmiconfig: 7.1.0 - cosmiconfig-typescript-loader: 4.3.0(@types/node@18.6.2)(cosmiconfig@7.1.0)(ts-node@10.9.1)(typescript@4.8.2) - debounce: 1.2.1 - detect-indent: 6.1.0 - graphql: 16.6.0 - graphql-config: 4.4.1(@types/node@18.6.2)(cosmiconfig-typescript-loader@4.3.0)(graphql@16.6.0) - inquirer: 8.2.5 - is-glob: 4.0.3 - json-to-pretty-yaml: 1.2.2 - listr2: 4.0.5 - log-symbols: 4.1.0 - shell-quote: 1.8.0 - string-env-interpolation: 1.0.1 - ts-log: 2.2.5 - ts-node: 10.9.1(@types/node@18.6.2)(typescript@4.8.2) - tslib: 2.5.0 - yaml: 1.10.2 - yargs: 17.6.2 - transitivePeerDependencies: - - '@babel/core' - - '@swc/core' - - '@swc/wasm' - - '@types/node' - - bufferutil - - cosmiconfig-toml-loader - - encoding - - enquirer - - supports-color - - typescript - - utf-8-validate - dev: true - - /@graphql-codegen/core@2.6.8(graphql@16.6.0): - resolution: {integrity: sha512-JKllNIipPrheRgl+/Hm/xuWMw9++xNQ12XJR/OHHgFopOg4zmN3TdlRSyYcv/K90hCFkkIwhlHFUQTfKrm8rxQ==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.6.0) - '@graphql-tools/schema': 9.0.15(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.4.1 - dev: true - - /@graphql-codegen/import-types-preset@2.2.6(graphql@16.6.0): - resolution: {integrity: sha512-Lo2ITOln3UVdyyEPiijj8bVhVg0Ghp/JzHXA2LXxrJVCRbXizQhVC2vjiaWTjMskPt9Zub0yIoce4+RrbsXKcg==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/add': 3.2.3(graphql@16.6.0) - '@graphql-codegen/plugin-helpers': 2.7.2(graphql@16.6.0) - '@graphql-codegen/visitor-plugin-common': 2.13.1(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.4.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@graphql-codegen/plugin-helpers@2.7.2(graphql@16.6.0): - resolution: {integrity: sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-tools/utils': 8.13.1(graphql@16.6.0) - change-case-all: 1.0.14 - common-tags: 1.8.2 - graphql: 16.6.0 - import-from: 4.0.0 - lodash: 4.17.21 - tslib: 2.4.1 - dev: true - - /@graphql-codegen/plugin-helpers@3.1.2(graphql@16.6.0): - resolution: {integrity: sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - change-case-all: 1.0.15 - common-tags: 1.8.2 - graphql: 16.6.0 - import-from: 4.0.0 - lodash: 4.17.21 - tslib: 2.4.1 - dev: true - - /@graphql-codegen/schema-ast@2.6.1(graphql@16.6.0): - resolution: {integrity: sha512-5TNW3b1IHJjCh07D2yQNGDQzUpUl2AD+GVe1Dzjqyx/d2Fn0TPMxLsHsKPS4Plg4saO8FK/QO70wLsP7fdbQ1w==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.4.1 - dev: true - - /@graphql-codegen/typescript-graphql-request@4.5.8(graphql-request@5.1.0)(graphql-tag@2.12.6)(graphql@16.6.0): - resolution: {integrity: sha512-XsuAA35Ou03LsklNgnIWXZ5HOHsJ5w1dBuDKtvqM9rD0cAI8x0f4TY0n6O1EraSBSvyHLP3npb1lOTPZzG2TjA==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - graphql-request: ^3.4.0 || ^4.0.0 || ^5.0.0 - graphql-tag: ^2.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 2.7.2(graphql@16.6.0) - '@graphql-codegen/visitor-plugin-common': 2.13.1(graphql@16.6.0) - auto-bind: 4.0.0 - graphql: 16.6.0 - graphql-request: 5.1.0(graphql@16.6.0) - graphql-tag: 2.12.6(graphql@16.6.0) - tslib: 2.4.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@graphql-codegen/typescript-operations@2.5.13(graphql@16.6.0): - resolution: {integrity: sha512-3vfR6Rx6iZU0JRt29GBkFlrSNTM6t+MSLF86ChvL4d/Jfo/JYAGuB3zNzPhirHYzJPCvLOAx2gy9ID1ltrpYiw==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.6.0) - '@graphql-codegen/typescript': 2.8.8(graphql@16.6.0) - '@graphql-codegen/visitor-plugin-common': 2.13.8(graphql@16.6.0) - auto-bind: 4.0.0 - graphql: 16.6.0 - tslib: 2.4.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@graphql-codegen/typescript@2.8.8(graphql@16.6.0): - resolution: {integrity: sha512-A0oUi3Oy6+DormOlrTC4orxT9OBZkIglhbJBcDmk34jAKKUgesukXRd4yOhmTrnbchpXz2T8IAOFB3FWIaK4Rw==} - peerDependencies: - graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.6.0) - '@graphql-codegen/schema-ast': 2.6.1(graphql@16.6.0) - '@graphql-codegen/visitor-plugin-common': 2.13.8(graphql@16.6.0) - auto-bind: 4.0.0 - graphql: 16.6.0 - tslib: 2.4.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@graphql-codegen/visitor-plugin-common@2.13.1(graphql@16.6.0): - resolution: {integrity: sha512-mD9ufZhDGhyrSaWQGrU1Q1c5f01TeWtSWy/cDwXYjJcHIj1Y/DG2x0tOflEfCvh5WcnmHNIw4lzDsg1W7iFJEg==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 2.7.2(graphql@16.6.0) - '@graphql-tools/optimize': 1.3.1(graphql@16.6.0) - '@graphql-tools/relay-operation-optimizer': 6.5.16(graphql@16.6.0) - '@graphql-tools/utils': 8.13.1(graphql@16.6.0) - auto-bind: 4.0.0 - change-case-all: 1.0.14 - dependency-graph: 0.11.0 - graphql: 16.6.0 - graphql-tag: 2.12.6(graphql@16.6.0) - parse-filepath: 1.0.2 - tslib: 2.4.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@graphql-codegen/visitor-plugin-common@2.13.8(graphql@16.6.0): - resolution: {integrity: sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.6.0) - '@graphql-tools/optimize': 1.3.1(graphql@16.6.0) - '@graphql-tools/relay-operation-optimizer': 6.5.16(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - auto-bind: 4.0.0 - change-case-all: 1.0.15 - dependency-graph: 0.11.0 - graphql: 16.6.0 - graphql-tag: 2.12.6(graphql@16.6.0) - parse-filepath: 1.0.2 - tslib: 2.4.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@graphql-tools/apollo-engine-loader@7.3.23(@types/node@18.6.2)(graphql@16.6.0): - resolution: {integrity: sha512-OGS0fGUeqBn2NNSfDBVIV7mjch6/7M4JCxvA7fpvVUAmdjjnQ6Z/CGyLIH2bv1eNv75gX/Kkj3baI0lwAWzsXw==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@ardatan/sync-fetch': 0.0.1 - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@whatwg-node/fetch': 0.6.6(@types/node@18.6.2) - graphql: 16.6.0 - tslib: 2.5.0 - transitivePeerDependencies: - - '@types/node' - - encoding - dev: true - - /@graphql-tools/batch-execute@8.5.16(graphql@16.6.0): - resolution: {integrity: sha512-x/gXA6R1Q/qigT5LDesZYemErzFYvBBuTaVgiIJuE2wG6oMV1cln0O35Z7WVQw6H3I4vF7cCG7c7wKSoC+3z4Q==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - dataloader: 2.1.0 - graphql: 16.6.0 - tslib: 2.5.0 - value-or-promise: 1.0.12 - dev: true - - /@graphql-tools/code-file-loader@7.3.18(@babel/core@7.19.6)(graphql@16.6.0): - resolution: {integrity: sha512-DK0YjsJWKkLF6HQYuuqiDwMr9rwRojm8yR/T+J8vXCOR4ndYa1EvUm9wRHPhxHVOYeptO2u+APoWNEhuMN9Hbw==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/graphql-tag-pluck': 7.4.4(@babel/core@7.19.6)(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - globby: 11.1.0 - graphql: 16.6.0 - tslib: 2.5.0 - unixify: 1.0.0 - transitivePeerDependencies: - - '@babel/core' - - supports-color - dev: true - - /@graphql-tools/delegate@9.0.25(graphql@16.6.0): - resolution: {integrity: sha512-M7DMrPx8uEjXUshkki0ufcL//9Dj12eR3vykvteFB6odYL9cX5dhZC9l1D2IdQRuHzLMskhkhRtfnXRoa82KTA==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/batch-execute': 8.5.16(graphql@16.6.0) - '@graphql-tools/executor': 0.0.13(graphql@16.6.0) - '@graphql-tools/schema': 9.0.15(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - dataloader: 2.1.0 - graphql: 16.6.0 - tslib: 2.5.0 - value-or-promise: 1.0.12 - dev: true - - /@graphql-tools/executor-graphql-ws@0.0.9(graphql@16.6.0): - resolution: {integrity: sha512-S323OGzc8TQHOw8n7pFSl1+oG5pzhQhXRmgW6sAvA1F79FLjQ95TltEa6jSH7Jqw+tZobMyylJ13CQ1zFDjBPg==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@repeaterjs/repeater': 3.0.4 - '@types/ws': 8.5.4 - graphql: 16.6.0 - graphql-ws: 5.11.3(graphql@16.6.0) - isomorphic-ws: 5.0.0(ws@8.12.0) - tslib: 2.5.0 - ws: 8.12.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: true - - /@graphql-tools/executor-http@0.1.4(@types/node@18.6.2)(graphql@16.6.0): - resolution: {integrity: sha512-6NGxLA9Z/cSOLExxfgddXqoS9JHr0QzvC4YmrjeMz533eW/SDnCf+4803PxkLi0j5CUTUPBnt9hC79l1AD2rZQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@repeaterjs/repeater': 3.0.4 - '@whatwg-node/fetch': 0.6.5(@types/node@18.6.2) - dset: 3.1.2 - extract-files: 11.0.0 - graphql: 16.6.0 - meros: 1.2.1(@types/node@18.6.2) - tslib: 2.5.0 - value-or-promise: 1.0.12 - transitivePeerDependencies: - - '@types/node' - dev: true - - /@graphql-tools/executor-legacy-ws@0.0.7(graphql@16.6.0): - resolution: {integrity: sha512-tSBJE/uv/r0iQjsU16QZkRLLCT0cmVWPqn8NVuAp3yqEeYlU7bzf38L4wNYTn46OHIYElFxXBFsGgMdyvrQLzg==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@types/ws': 8.5.4 - graphql: 16.6.0 - isomorphic-ws: 5.0.0(ws@8.12.0) - tslib: 2.5.0 - ws: 8.12.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: true - - /@graphql-tools/executor@0.0.13(graphql@16.6.0): - resolution: {integrity: sha512-bZ7QdUV5URLCjD/WuDkvyROYoDVoueTN5W1PatkcN949lwIwEKXUW6y3gRSpiZjXw8IH4/NmN3xPk10OT1emRw==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@graphql-typed-document-node/core': 3.1.1(graphql@16.6.0) - '@repeaterjs/repeater': 3.0.4 - graphql: 16.6.0 - tslib: 2.5.0 - value-or-promise: 1.0.12 - dev: true - - /@graphql-tools/git-loader@7.2.17(@babel/core@7.19.6)(graphql@16.6.0): - resolution: {integrity: sha512-VbJQEgjy3oH0IQvkCJFKsIatep9Qv8mToBf0QSMXvS9fZkLM5wwTM4KPtw0Loim/1BAAnomBpHy6I4kiwqYU4A==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/graphql-tag-pluck': 7.4.4(@babel/core@7.19.6)(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - is-glob: 4.0.3 - micromatch: 4.0.5 - tslib: 2.5.0 - unixify: 1.0.0 - transitivePeerDependencies: - - '@babel/core' - - supports-color - dev: true - - /@graphql-tools/github-loader@7.3.24(@babel/core@7.19.6)(@types/node@18.6.2)(graphql@16.6.0): - resolution: {integrity: sha512-URlH4tJFk/a97tIFTzAZuQTiFiQrwKjr0fKGohbyKMMycBf82XZ6F199PZP3GtigNmzTqV/vTkf1VLTJU97jRw==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@ardatan/sync-fetch': 0.0.1 - '@graphql-tools/graphql-tag-pluck': 7.4.4(@babel/core@7.19.6)(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@whatwg-node/fetch': 0.6.6(@types/node@18.6.2) - graphql: 16.6.0 - tslib: 2.5.0 - transitivePeerDependencies: - - '@babel/core' - - '@types/node' - - encoding - - supports-color - dev: true - - /@graphql-tools/graphql-file-loader@7.5.15(graphql@16.6.0): - resolution: {integrity: sha512-K6yOfKkQdXQRBl+UY4FzGdoSzGG09GLPZv4q7OFp8do16CXhaxAI+kmJvsvrutSyBfLETPTkCHtzFmdRmTeLpg==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/import': 6.7.16(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - globby: 11.1.0 - graphql: 16.6.0 - tslib: 2.5.0 - unixify: 1.0.0 - dev: true - - /@graphql-tools/graphql-tag-pluck@7.4.4(@babel/core@7.19.6)(graphql@16.6.0): - resolution: {integrity: sha512-yHIEcapR/kVSrn4W4Nf3FYpJKPcoGvJbdbye8TnW3dD5GkG4UqVnKuyqFvQPOhgqXKbloFZqUhNqEuyqxqIPRw==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@babel/parser': 7.20.15 - '@babel/plugin-syntax-import-assertions': 7.20.0(@babel/core@7.19.6) - '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.5.0 - transitivePeerDependencies: - - '@babel/core' - - supports-color - dev: true - - /@graphql-tools/import@6.7.16(graphql@16.6.0): - resolution: {integrity: sha512-m07u+8YsBtKg5w5BG04KFTd59PCAPMAy5Dv/NlR4zCiH/Zbpy5PoetokCZKDrFHYUzjPlm8r//vfCG+JTvHw7g==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - resolve-from: 5.0.0 - tslib: 2.5.0 - dev: true - - /@graphql-tools/json-file-loader@7.4.16(graphql@16.6.0): - resolution: {integrity: sha512-9MsqpwIrCx0l880V0dud01DhkwYwqCIlZlCA3bN+TExWa9U3aZhyPO/5BWQU6W52wKk61TvyN6agUa+f4R7jVQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - globby: 11.1.0 - graphql: 16.6.0 - tslib: 2.5.0 - unixify: 1.0.0 - dev: true - - /@graphql-tools/load@7.8.11(graphql@16.6.0): - resolution: {integrity: sha512-pVn3fYP/qZ3m2NE86gSexyZpEmvTSUe+OIRfWBM60a4L/SycMxgVfYB5+PyDCzruFZg/didIG3v7RfPlZ7zNTQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/schema': 9.0.15(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - p-limit: 3.1.0 - tslib: 2.5.0 - dev: true - - /@graphql-tools/merge@8.3.17(graphql@16.6.0): - resolution: {integrity: sha512-CLzz49lc6BavPhH9gPRm0sJeNA7kC/tF/jLUTQsyef6xj82Jw3rqIJ9PE+bk1cqPCOG01WLOfquBu445OMDO2g==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.5.0 - dev: true - - /@graphql-tools/optimize@1.3.1(graphql@16.6.0): - resolution: {integrity: sha512-5j5CZSRGWVobt4bgRRg7zhjPiSimk+/zIuColih8E8DxuFOaJ+t0qu7eZS5KXWBkjcd4BPNuhUPpNlEmHPqVRQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - graphql: 16.6.0 - tslib: 2.5.0 - dev: true - - /@graphql-tools/prisma-loader@7.2.60(@types/node@18.6.2)(graphql@16.6.0): - resolution: {integrity: sha512-6C/Hicwu/luLlaIqSud3YHJ1HbrIsZ0jHfxWju9aWs3dJLSwRv8Lgw1eHSoWFDEZjc+zNETYNe9GgUwt4BBZzQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/url-loader': 7.17.9(@types/node@18.6.2)(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@types/js-yaml': 4.0.5 - '@types/json-stable-stringify': 1.0.34 - '@types/jsonwebtoken': 9.0.1 - chalk: 4.1.2 - debug: 4.3.4 - dotenv: 16.0.2 - graphql: 16.6.0 - graphql-request: 5.1.0(graphql@16.6.0) - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - isomorphic-fetch: 3.0.0 - js-yaml: 4.1.0 - json-stable-stringify: 1.0.2 - jsonwebtoken: 9.0.0 - lodash: 4.17.21 - scuid: 1.1.0 - tslib: 2.5.0 - yaml-ast-parser: 0.0.43 - transitivePeerDependencies: - - '@types/node' - - bufferutil - - encoding - - supports-color - - utf-8-validate - dev: true - - /@graphql-tools/relay-operation-optimizer@6.5.16(graphql@16.6.0): - resolution: {integrity: sha512-g7P11WqrU6h/sRSe6KJULsNUt+5rdwD7mQpnjpKouhXAz/iNKwiUS0BEkkLjkneDkRVvrX0oqBB43VaMaW+gpQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@ardatan/relay-compiler': 12.0.0(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.5.0 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /@graphql-tools/schema@9.0.15(graphql@16.6.0): - resolution: {integrity: sha512-p2DbpkOBcsi+yCEjwoS+r4pJ5z+3JjlJdhbPkCwC4q8lGf5r93dVYrExOrqGKTU5kxLXI/mxabSxcunjNIsDIg==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/merge': 8.3.17(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.5.0 - value-or-promise: 1.0.12 - dev: true - - /@graphql-tools/url-loader@7.17.9(@types/node@18.6.2)(graphql@16.6.0): - resolution: {integrity: sha512-qAXQ9Tr/Am2hEelGVLCfO/YOyCMzCd4FyWMRRqcoMYIaK91arIb5X13pgILD28SUN+6H3NDsx7fgq/Z/OhwGrQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@ardatan/sync-fetch': 0.0.1 - '@graphql-tools/delegate': 9.0.25(graphql@16.6.0) - '@graphql-tools/executor-graphql-ws': 0.0.9(graphql@16.6.0) - '@graphql-tools/executor-http': 0.1.4(@types/node@18.6.2)(graphql@16.6.0) - '@graphql-tools/executor-legacy-ws': 0.0.7(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - '@graphql-tools/wrap': 9.3.4(graphql@16.6.0) - '@types/ws': 8.5.4 - '@whatwg-node/fetch': 0.6.6(@types/node@18.6.2) - graphql: 16.6.0 - isomorphic-ws: 5.0.0(ws@8.12.0) - tslib: 2.5.0 - value-or-promise: 1.0.12 - ws: 8.12.0 - transitivePeerDependencies: - - '@types/node' - - bufferutil - - encoding - - utf-8-validate - dev: true - - /@graphql-tools/utils@8.13.1(graphql@16.6.0): - resolution: {integrity: sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - graphql: 16.6.0 - tslib: 2.5.0 - dev: true - - /@graphql-tools/utils@9.2.0(graphql@16.6.0): - resolution: {integrity: sha512-s3lEG1iYkyYEnKCWrIFECX3XH2wmZvbg6Ir3udCvIDynq+ydaO7JQXobclpPtwSJtjlS353haF//6V7mnBQ4bg==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-typed-document-node/core': 3.1.1(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.5.0 - dev: true - - /@graphql-tools/wrap@9.3.4(graphql@16.6.0): - resolution: {integrity: sha512-MJY6lZqi+j96izjOYOLk5fys34oiLt7U34SQ4Wd6V/sy1utVMbh2H7XiZAuDJ38JIKmr72qN7kLgNcnNOxXjHQ==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - '@graphql-tools/delegate': 9.0.25(graphql@16.6.0) - '@graphql-tools/schema': 9.0.15(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.5.0 - value-or-promise: 1.0.12 - dev: true - - /@graphql-typed-document-node/core@3.1.1(graphql@16.6.0): - resolution: {integrity: sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - graphql: 16.6.0 - dev: true - - /@humanwhocodes/config-array@0.10.7: - resolution: {integrity: sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@humanwhocodes/gitignore-to-minimatch@1.0.2: - resolution: {integrity: sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==} - dev: true - - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true - - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - dev: true - - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true - - /@jest/console@28.1.3: - resolution: {integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - chalk: 4.1.2 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - slash: 3.0.0 - dev: true - - /@jest/core@28.1.3(ts-node@10.9.1): - resolution: {integrity: sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/console': 28.1.3 - '@jest/reporters': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.5.0 - exit: 0.1.2 - graceful-fs: 4.2.10 - jest-changed-files: 28.1.3 - jest-config: 28.1.3(@types/node@18.6.2)(ts-node@10.9.1) - jest-haste-map: 28.1.3 - jest-message-util: 28.1.3 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-resolve-dependencies: 28.1.3 - jest-runner: 28.1.3 - jest-runtime: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - jest-validate: 28.1.3 - jest-watcher: 28.1.3 - micromatch: 4.0.5 - pretty-format: 28.1.3 - rimraf: 3.0.2 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - - /@jest/environment@28.1.3: - resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - jest-mock: 28.1.3 - dev: true - - /@jest/expect-utils@28.1.3: - resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-get-type: 28.0.2 - dev: true - - /@jest/expect@28.1.3: - resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - expect: 28.1.3 - jest-snapshot: 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/fake-timers@28.1.3: - resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.6.2 - jest-message-util: 28.1.3 - jest-mock: 28.1.3 - jest-util: 28.1.3 - dev: true - - /@jest/globals@28.1.3: - resolution: {integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/expect': 28.1.3 - '@jest/types': 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/reporters@28.1.3: - resolution: {integrity: sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.6.2 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.10 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.1 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - jest-worker: 28.1.3 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - terminal-link: 2.1.1 - v8-to-istanbul: 9.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/schemas@28.1.3: - resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@sinclair/typebox': 0.24.51 - dev: true - - /@jest/source-map@28.1.2: - resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - callsites: 3.1.0 - graceful-fs: 4.2.10 - dev: true - - /@jest/test-result@28.1.3: - resolution: {integrity: sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/console': 28.1.3 - '@jest/types': 28.1.3 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 - dev: true - - /@jest/test-sequencer@28.1.3: - resolution: {integrity: sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/test-result': 28.1.3 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - slash: 3.0.0 - dev: true - - /@jest/transform@28.1.3: - resolution: {integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/core': 7.19.6 - '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.17 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 1.9.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - jest-regex-util: 28.0.2 - jest-util: 28.1.3 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/types@28.1.3: - resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/schemas': 28.1.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 18.6.2 - '@types/yargs': 17.0.13 - chalk: 4.1.2 - dev: true - - /@jridgewell/gen-mapping@0.1.1: - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jridgewell/gen-mapping@0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@jridgewell/resolve-uri@3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/source-map@0.3.3: - resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} - dependencies: - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true - - /@jridgewell/trace-mapping@0.3.17: - resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jsdevtools/ono@7.1.3: - resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} - dev: true - - /@noble/hashes@1.1.3: - resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} - dev: false - - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true - - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.13.0 - dev: true - - /@peculiar/asn1-schema@2.3.3: - resolution: {integrity: sha512-6GptMYDMyWBHTUKndHaDsRZUO/XMSgIns2krxcm2L7SEExRHwawFvSwNBhqNPR9HJwv3MruAiF1bhN0we6j6GQ==} - dependencies: - asn1js: 3.0.5 - pvtsutils: 1.3.2 - tslib: 2.5.0 - dev: true - - /@peculiar/json-schema@1.1.12: - resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} - engines: {node: '>=8.0.0'} - dependencies: - tslib: 2.5.0 - dev: true - - /@peculiar/webcrypto@1.4.1: - resolution: {integrity: sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==} - engines: {node: '>=10.12.0'} - dependencies: - '@peculiar/asn1-schema': 2.3.3 - '@peculiar/json-schema': 1.1.12 - pvtsutils: 1.3.2 - tslib: 2.5.0 - webcrypto-core: 1.7.5 - dev: true - - /@repeaterjs/repeater@3.0.4: - resolution: {integrity: sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==} - dev: true - - /@scure/base@1.1.1: - resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} - dev: false - - /@scure/bip39@1.1.0: - resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} - dependencies: - '@noble/hashes': 1.1.3 - '@scure/base': 1.1.1 - dev: false - - /@sinclair/typebox@0.24.51: - resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} - dev: true - - /@sinonjs/commons@1.8.4: - resolution: {integrity: sha512-RpmQdHVo8hCEHDVpO39zToS9jOhR6nw+/lQAzRNq9ErrGV9IeHM71XCn68svVl/euFeVW6BWX4p35gkhbOcSIQ==} - dependencies: - type-detect: 4.0.8 - dev: true - - /@sinonjs/fake-timers@9.1.2: - resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} - dependencies: - '@sinonjs/commons': 1.8.4 - dev: true - - /@tootallnate/once@2.0.0: - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - dev: true - - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.3: - resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} - dev: true - - /@types/babel__core@7.1.19: - resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} - dependencies: - '@babel/parser': 7.20.1 - '@babel/types': 7.20.0 - '@types/babel__generator': 7.6.4 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.18.2 - dev: true - - /@types/babel__generator@7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@types/babel__template@7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - dependencies: - '@babel/parser': 7.20.1 - '@babel/types': 7.20.0 - dev: true - - /@types/babel__traverse@7.18.2: - resolution: {integrity: sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@types/eslint-scope@3.7.4: - resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} - dependencies: - '@types/eslint': 8.37.0 - '@types/estree': 1.0.1 - dev: true - - /@types/eslint@8.37.0: - resolution: {integrity: sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==} - dependencies: - '@types/estree': 1.0.1 - '@types/json-schema': 7.0.11 - dev: true - - /@types/estree@1.0.1: - resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} - dev: true - - /@types/graceful-fs@4.1.5: - resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} - dependencies: - '@types/node': 18.6.2 - dev: true - - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true - - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.4 - dev: true - - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - dependencies: - '@types/istanbul-lib-report': 3.0.0 - dev: true - - /@types/jest@28.1.8: - resolution: {integrity: sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw==} - dependencies: - expect: 28.1.3 - pretty-format: 28.1.3 - dev: true - - /@types/js-yaml@4.0.5: - resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==} - dev: true - - /@types/json-schema@7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} - dev: true - - /@types/json-stable-stringify@1.0.34: - resolution: {integrity: sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw==} - dev: true - - /@types/json5@0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: true - - /@types/jsonwebtoken@9.0.1: - resolution: {integrity: sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==} - dependencies: - '@types/node': 18.6.2 - dev: true - - /@types/node@18.6.2: - resolution: {integrity: sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ==} - dev: true - - /@types/parse-json@4.0.0: - resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} - dev: true - - /@types/prettier@2.7.1: - resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} - dev: true - - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - dev: true - - /@types/ws@8.5.4: - resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==} - dependencies: - '@types/node': 18.6.2 - dev: true - - /@types/yargs-parser@21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true - - /@types/yargs@17.0.13: - resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==} - dependencies: - '@types/yargs-parser': 21.0.0 - dev: true - - /@typescript-eslint/eslint-plugin@5.36.2(@typescript-eslint/parser@5.36.2)(eslint@8.23.0)(typescript@4.8.2): - resolution: {integrity: sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/parser': 5.36.2(eslint@8.23.0)(typescript@4.8.2) - '@typescript-eslint/scope-manager': 5.36.2 - '@typescript-eslint/type-utils': 5.36.2(eslint@8.23.0)(typescript@4.8.2) - '@typescript-eslint/utils': 5.36.2(eslint@8.23.0)(typescript@4.8.2) - debug: 4.3.4 - eslint: 8.23.0 - functional-red-black-tree: 1.0.1 - ignore: 5.2.0 - regexpp: 3.2.0 - semver: 7.3.8 - tsutils: 3.21.0(typescript@4.8.2) - typescript: 4.8.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/parser@5.36.2(eslint@8.23.0)(typescript@4.8.2): - resolution: {integrity: sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.36.2 - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/typescript-estree': 5.36.2(typescript@4.8.2) - debug: 4.3.4 - eslint: 8.23.0 - typescript: 4.8.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/scope-manager@5.36.2: - resolution: {integrity: sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/visitor-keys': 5.36.2 - dev: true - - /@typescript-eslint/type-utils@5.36.2(eslint@8.23.0)(typescript@4.8.2): - resolution: {integrity: sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.36.2(typescript@4.8.2) - '@typescript-eslint/utils': 5.36.2(eslint@8.23.0)(typescript@4.8.2) - debug: 4.3.4 - eslint: 8.23.0 - tsutils: 3.21.0(typescript@4.8.2) - typescript: 4.8.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/types@5.36.2: - resolution: {integrity: sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@typescript-eslint/typescript-estree@5.36.2(typescript@4.8.2): - resolution: {integrity: sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/visitor-keys': 5.36.2 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.8 - tsutils: 3.21.0(typescript@4.8.2) - typescript: 4.8.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils@5.36.2(eslint@8.23.0)(typescript@4.8.2): - resolution: {integrity: sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.36.2 - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/typescript-estree': 5.36.2(typescript@4.8.2) - eslint: 8.23.0 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0(eslint@8.23.0) - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys@5.36.2: - resolution: {integrity: sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.36.2 - eslint-visitor-keys: 3.3.0 - dev: true - - /@webassemblyjs/ast@1.11.5: - resolution: {integrity: sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==} - dependencies: - '@webassemblyjs/helper-numbers': 1.11.5 - '@webassemblyjs/helper-wasm-bytecode': 1.11.5 - dev: true - - /@webassemblyjs/floating-point-hex-parser@1.11.5: - resolution: {integrity: sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==} - dev: true - - /@webassemblyjs/helper-api-error@1.11.5: - resolution: {integrity: sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==} - dev: true - - /@webassemblyjs/helper-buffer@1.11.5: - resolution: {integrity: sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==} - dev: true - - /@webassemblyjs/helper-numbers@1.11.5: - resolution: {integrity: sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA==} - dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.11.5 - '@webassemblyjs/helper-api-error': 1.11.5 - '@xtuc/long': 4.2.2 - dev: true - - /@webassemblyjs/helper-wasm-bytecode@1.11.5: - resolution: {integrity: sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==} - dev: true - - /@webassemblyjs/helper-wasm-section@1.11.5: - resolution: {integrity: sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA==} - dependencies: - '@webassemblyjs/ast': 1.11.5 - '@webassemblyjs/helper-buffer': 1.11.5 - '@webassemblyjs/helper-wasm-bytecode': 1.11.5 - '@webassemblyjs/wasm-gen': 1.11.5 - dev: true - - /@webassemblyjs/ieee754@1.11.5: - resolution: {integrity: sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==} - dependencies: - '@xtuc/ieee754': 1.2.0 - dev: true - - /@webassemblyjs/leb128@1.11.5: - resolution: {integrity: sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==} - dependencies: - '@xtuc/long': 4.2.2 - dev: true - - /@webassemblyjs/utf8@1.11.5: - resolution: {integrity: sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==} - dev: true - - /@webassemblyjs/wasm-edit@1.11.5: - resolution: {integrity: sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ==} - dependencies: - '@webassemblyjs/ast': 1.11.5 - '@webassemblyjs/helper-buffer': 1.11.5 - '@webassemblyjs/helper-wasm-bytecode': 1.11.5 - '@webassemblyjs/helper-wasm-section': 1.11.5 - '@webassemblyjs/wasm-gen': 1.11.5 - '@webassemblyjs/wasm-opt': 1.11.5 - '@webassemblyjs/wasm-parser': 1.11.5 - '@webassemblyjs/wast-printer': 1.11.5 - dev: true - - /@webassemblyjs/wasm-gen@1.11.5: - resolution: {integrity: sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA==} - dependencies: - '@webassemblyjs/ast': 1.11.5 - '@webassemblyjs/helper-wasm-bytecode': 1.11.5 - '@webassemblyjs/ieee754': 1.11.5 - '@webassemblyjs/leb128': 1.11.5 - '@webassemblyjs/utf8': 1.11.5 - dev: true - - /@webassemblyjs/wasm-opt@1.11.5: - resolution: {integrity: sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw==} - dependencies: - '@webassemblyjs/ast': 1.11.5 - '@webassemblyjs/helper-buffer': 1.11.5 - '@webassemblyjs/wasm-gen': 1.11.5 - '@webassemblyjs/wasm-parser': 1.11.5 - dev: true - - /@webassemblyjs/wasm-parser@1.11.5: - resolution: {integrity: sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew==} - dependencies: - '@webassemblyjs/ast': 1.11.5 - '@webassemblyjs/helper-api-error': 1.11.5 - '@webassemblyjs/helper-wasm-bytecode': 1.11.5 - '@webassemblyjs/ieee754': 1.11.5 - '@webassemblyjs/leb128': 1.11.5 - '@webassemblyjs/utf8': 1.11.5 - dev: true - - /@webassemblyjs/wast-printer@1.11.5: - resolution: {integrity: sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA==} - dependencies: - '@webassemblyjs/ast': 1.11.5 - '@xtuc/long': 4.2.2 - dev: true - - /@whatwg-node/events@0.0.2: - resolution: {integrity: sha512-WKj/lI4QjnLuPrim0cfO7i+HsDSXHxNv1y0CrJhdntuO3hxWZmnXCwNDnwOvry11OjRin6cgWNF+j/9Pn8TN4w==} - dev: true - - /@whatwg-node/fetch@0.6.5(@types/node@18.6.2): - resolution: {integrity: sha512-3XQ78RAMX8Az0LlUqMoGM3jbT+FE0S+IKr4yiTiqzQ5S/pNxD52K/kFLcLQiEbL+3rkk/glCHqjxF1QI5155Ig==} - dependencies: - '@peculiar/webcrypto': 1.4.1 - '@whatwg-node/node-fetch': 0.0.1(@types/node@18.6.2) - busboy: 1.6.0 - urlpattern-polyfill: 6.0.2 - web-streams-polyfill: 3.2.1 - transitivePeerDependencies: - - '@types/node' - dev: true - - /@whatwg-node/fetch@0.6.6(@types/node@18.6.2): - resolution: {integrity: sha512-8kB/Pp0knQVjbm3O15h1ATKOZ7n8GXMow3z8ptVTaRmiOMnCnA9bn7gKTLWFBdD84zzWFzPp6C9pB3vsndJKlQ==} - dependencies: - '@peculiar/webcrypto': 1.4.1 - '@whatwg-node/node-fetch': 0.0.2(@types/node@18.6.2) - busboy: 1.6.0 - urlpattern-polyfill: 6.0.2 - web-streams-polyfill: 3.2.1 - transitivePeerDependencies: - - '@types/node' - dev: true - - /@whatwg-node/node-fetch@0.0.1(@types/node@18.6.2): - resolution: {integrity: sha512-dMbh604yf2jl37IzvYGA6z3heQg3dMzlqoNsiNToe46SVmKusfJXGf4KYIuiJTzh9mEEu/uVF//QakUfsLJpwA==} - peerDependencies: - '@types/node': ^18.0.6 - dependencies: - '@types/node': 18.6.2 - '@whatwg-node/events': 0.0.2 - busboy: 1.6.0 - tslib: 2.5.0 - dev: true - - /@whatwg-node/node-fetch@0.0.2(@types/node@18.6.2): - resolution: {integrity: sha512-Xs3kunumaSWTHDjKJATP9r2AhwhwPh8miQQHi3aI64MwBSrFsolBUUyCkOJe2geDuHggoNycfnU85HP528odWg==} - peerDependencies: - '@types/node': ^18.0.6 - dependencies: - '@types/node': 18.6.2 - '@whatwg-node/events': 0.0.2 - busboy: 1.6.0 - tslib: 2.5.0 - dev: true - - /@xtuc/ieee754@1.2.0: - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - dev: true - - /@xtuc/long@4.2.2: - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - dev: true - - /acorn-import-assertions@1.8.0(acorn@8.8.1): - resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} - peerDependencies: - acorn: ^8 - dependencies: - acorn: 8.8.1 - dev: true - - /acorn-jsx@5.3.2(acorn@8.8.1): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.8.1 - dev: true - - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn@8.8.1: - resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: true - - /ajv-keywords@3.5.2(ajv@6.12.6): - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - dependencies: - ajv: 6.12.6 - dev: true - - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - dev: true - - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true - - /any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - dev: true - - /anymatch@3.1.2: - resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} - engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - - /array-includes@3.1.5: - resolution: {integrity: sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - get-intrinsic: 1.1.3 - is-string: 1.0.7 - dev: true - - /array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - /array.prototype.flat@1.3.1: - resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - es-shim-unscopables: 1.0.0 - dev: true - - /asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - dev: true - - /asn1js@3.0.5: - resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} - engines: {node: '>=12.0.0'} - dependencies: - pvtsutils: 1.3.2 - pvutils: 1.1.3 - tslib: 2.5.0 - dev: true - - /astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - dev: true - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - /auto-bind@4.0.0: - resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==} - engines: {node: '>=8'} - dev: true - - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /babel-jest@28.1.3(@babel/core@7.19.6): - resolution: {integrity: sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.19.6 - '@jest/transform': 28.1.3 - '@types/babel__core': 7.1.19 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 28.1.3(@babel/core@7.19.6) - chalk: 4.1.2 - graceful-fs: 4.2.10 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.19.0 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-jest-hoist@28.1.3: - resolution: {integrity: sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/template': 7.18.10 - '@babel/types': 7.20.0 - '@types/babel__core': 7.1.19 - '@types/babel__traverse': 7.18.2 - dev: true - - /babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: - resolution: {integrity: sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==} - dev: true - - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.19.6): - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.19.6 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.19.6) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.19.6) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.19.6) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.19.6) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.19.6) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.19.6) - dev: true - - /babel-preset-fbjs@3.4.0(@babel/core@7.19.6): - resolution: {integrity: sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.19.6 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.19.6) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.19.6) - '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.19.6) - '@babel/plugin-transform-arrow-functions': 7.20.7(@babel/core@7.19.6) - '@babel/plugin-transform-block-scoped-functions': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-transform-block-scoping': 7.20.15(@babel/core@7.19.6) - '@babel/plugin-transform-classes': 7.20.7(@babel/core@7.19.6) - '@babel/plugin-transform-computed-properties': 7.20.7(@babel/core@7.19.6) - '@babel/plugin-transform-destructuring': 7.20.7(@babel/core@7.19.6) - '@babel/plugin-transform-flow-strip-types': 7.19.0(@babel/core@7.19.6) - '@babel/plugin-transform-for-of': 7.18.8(@babel/core@7.19.6) - '@babel/plugin-transform-function-name': 7.18.9(@babel/core@7.19.6) - '@babel/plugin-transform-literals': 7.18.9(@babel/core@7.19.6) - '@babel/plugin-transform-member-expression-literals': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-transform-modules-commonjs': 7.20.11(@babel/core@7.19.6) - '@babel/plugin-transform-object-super': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-transform-parameters': 7.20.7(@babel/core@7.19.6) - '@babel/plugin-transform-property-literals': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-transform-react-jsx': 7.20.13(@babel/core@7.19.6) - '@babel/plugin-transform-shorthand-properties': 7.18.6(@babel/core@7.19.6) - '@babel/plugin-transform-spread': 7.20.7(@babel/core@7.19.6) - '@babel/plugin-transform-template-literals': 7.18.9(@babel/core@7.19.6) - babel-plugin-syntax-trailing-function-commas: 7.0.0-beta.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-preset-jest@28.1.3(@babel/core@7.19.6): - resolution: {integrity: sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.19.6 - babel-plugin-jest-hoist: 28.1.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.19.6) - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true - - /binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} - dev: true - - /bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.0 - dev: true - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - /browserslist@4.21.4: - resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001429 - electron-to-chromium: 1.4.284 - node-releases: 2.0.6 - update-browserslist-db: 1.0.10(browserslist@4.21.4) - dev: true - - /bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - dependencies: - fast-json-stable-stringify: 2.1.0 - dev: true - - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - dev: true - - /buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - dev: true - - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: true - - /bundle-require@3.1.2(esbuild@0.15.13): - resolution: {integrity: sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.13' - dependencies: - esbuild: 0.15.13 - load-tsconfig: 0.2.3 - dev: true - - /busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - dependencies: - streamsearch: 1.1.0 - dev: true - - /cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - dev: true - - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.1.3 - dev: true - - /call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - dev: true - - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true - - /camel-case@4.1.2: - resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} - dependencies: - pascal-case: 3.1.2 - tslib: 2.5.0 - dev: true - - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - dev: true - - /caniuse-lite@1.0.30001429: - resolution: {integrity: sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg==} - dev: true - - /capital-case@1.0.4: - resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} - dependencies: - no-case: 3.0.4 - tslib: 2.5.0 - upper-case-first: 2.0.2 - dev: true - - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /change-case-all@1.0.14: - resolution: {integrity: sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA==} - dependencies: - change-case: 4.1.2 - is-lower-case: 2.0.2 - is-upper-case: 2.0.2 - lower-case: 2.0.2 - lower-case-first: 2.0.2 - sponge-case: 1.0.1 - swap-case: 2.0.2 - title-case: 3.0.3 - upper-case: 2.0.2 - upper-case-first: 2.0.2 - dev: true - - /change-case-all@1.0.15: - resolution: {integrity: sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==} - dependencies: - change-case: 4.1.2 - is-lower-case: 2.0.2 - is-upper-case: 2.0.2 - lower-case: 2.0.2 - lower-case-first: 2.0.2 - sponge-case: 1.0.1 - swap-case: 2.0.2 - title-case: 3.0.3 - upper-case: 2.0.2 - upper-case-first: 2.0.2 - dev: true - - /change-case@4.1.2: - resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} - dependencies: - camel-case: 4.1.2 - capital-case: 1.0.4 - constant-case: 3.0.4 - dot-case: 3.0.4 - header-case: 2.0.4 - no-case: 3.0.4 - param-case: 3.0.4 - pascal-case: 3.1.2 - path-case: 3.0.4 - sentence-case: 3.0.4 - snake-case: 3.0.4 - tslib: 2.5.0 - dev: true - - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true - - /chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true - - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} - dependencies: - anymatch: 3.1.2 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /chrome-trace-event@1.0.3: - resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} - engines: {node: '>=6.0'} - dev: true - - /ci-info@3.5.0: - resolution: {integrity: sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==} - dev: true - - /cjs-module-lexer@1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: true - - /clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - dev: true - - /cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: true - - /cli-spinners@2.7.0: - resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} - engines: {node: '>=6'} - dev: true - - /cli-truncate@2.1.0: - resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} - engines: {node: '>=8'} - dependencies: - slice-ansi: 3.0.0 - string-width: 4.2.3 - dev: true - - /cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - dev: true - - /cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - dev: true - - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - dev: true - - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - - /collect-v8-coverage@1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: true - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - - /colorette@2.0.19: - resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} - dev: true - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true - - /commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - dev: true - - /commander@9.4.1: - resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} - engines: {node: ^12.20.0 || >=14} - dev: true - - /common-tags@1.8.2: - resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} - engines: {node: '>=4.0.0'} - dev: true - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /confusing-browser-globals@1.0.11: - resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} - dev: true - - /constant-case@3.0.4: - resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} - dependencies: - no-case: 3.0.4 - tslib: 2.5.0 - upper-case: 2.0.2 - dev: true - - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /cosmiconfig-typescript-loader@4.3.0(@types/node@18.6.2)(cosmiconfig@7.1.0)(ts-node@10.9.1)(typescript@4.8.2): - resolution: {integrity: sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==} - engines: {node: '>=12', npm: '>=6'} - peerDependencies: - '@types/node': '*' - cosmiconfig: '>=7' - ts-node: '>=10' - typescript: '>=3' - dependencies: - '@types/node': 18.6.2 - cosmiconfig: 7.1.0 - ts-node: 10.9.1(@types/node@18.6.2)(typescript@4.8.2) - typescript: 4.8.2 - dev: true - - /cosmiconfig@7.1.0: - resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} - engines: {node: '>=10'} - dependencies: - '@types/parse-json': 4.0.0 - import-fresh: 3.3.0 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 - dev: true - - /cosmiconfig@8.0.0: - resolution: {integrity: sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==} - engines: {node: '>=14'} - dependencies: - import-fresh: 3.3.0 - js-yaml: 4.1.0 - parse-json: 5.2.0 - path-type: 4.0.0 - dev: true - - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /cross-fetch@3.1.5: - resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} - dependencies: - node-fetch: 2.6.7 - transitivePeerDependencies: - - encoding - dev: true - - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - /dataloader@2.1.0: - resolution: {integrity: sha512-qTcEYLen3r7ojZNgVUaRggOI+KM7jrKxXeSHhogh/TWxYMeONEMqY+hmkobiYQozsGIyg9OYVzO4ZIfoB4I0pQ==} - dev: true - - /debounce@1.2.1: - resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} - dev: true - - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: true - - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - dev: true - - /dedent@0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: true - - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true - - /deepmerge@4.2.2: - resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} - engines: {node: '>=0.10.0'} - dev: true - - /defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - dependencies: - clone: 1.0.4 - dev: true - - /define-properties@1.1.4: - resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} - engines: {node: '>= 0.4'} - dependencies: - has-property-descriptors: 1.0.0 - object-keys: 1.1.1 - dev: true - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - /dependency-graph@0.11.0: - resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} - engines: {node: '>= 0.6.0'} - dev: true - - /detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - dev: true - - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true - - /diff-sequences@28.1.1: - resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - - /doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - dependencies: - no-case: 3.0.4 - tslib: 2.5.0 - dev: true - - /dotenv@16.0.2: - resolution: {integrity: sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==} - engines: {node: '>=12'} - dev: true - - /dset@3.1.2: - resolution: {integrity: sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==} - engines: {node: '>=4'} - dev: true - - /ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /electron-to-chromium@1.4.284: - resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} - dev: true - - /emittery@0.10.2: - resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} - engines: {node: '>=12'} - dev: true - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - - /enhanced-resolve@5.10.0: - resolution: {integrity: sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.10 - tapable: 2.2.1 - dev: true - - /enhanced-resolve@5.13.0: - resolution: {integrity: sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.10 - tapable: 2.2.1 - dev: true - - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es-abstract@1.20.4: - resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - es-to-primitive: 1.2.1 - function-bind: 1.1.1 - function.prototype.name: 1.1.5 - get-intrinsic: 1.1.3 - get-symbol-description: 1.0.0 - has: 1.0.3 - has-property-descriptors: 1.0.0 - has-symbols: 1.0.3 - internal-slot: 1.0.3 - is-callable: 1.2.7 - is-negative-zero: 2.0.2 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - is-string: 1.0.7 - is-weakref: 1.0.2 - object-inspect: 1.12.2 - object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.4.3 - safe-regex-test: 1.0.0 - string.prototype.trimend: 1.0.5 - string.prototype.trimstart: 1.0.5 - unbox-primitive: 1.0.2 - dev: true - - /es-module-lexer@1.2.1: - resolution: {integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==} - dev: true - - /es-shim-unscopables@1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} - dependencies: - has: 1.0.3 - dev: true - - /es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 - dev: true - - /esbuild-android-64@0.15.13: - resolution: {integrity: sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /esbuild-android-arm64@0.15.13: - resolution: {integrity: sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /esbuild-darwin-64@0.15.13: - resolution: {integrity: sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /esbuild-darwin-arm64@0.15.13: - resolution: {integrity: sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /esbuild-freebsd-64@0.15.13: - resolution: {integrity: sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-freebsd-arm64@0.15.13: - resolution: {integrity: sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-32@0.15.13: - resolution: {integrity: sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-64@0.15.13: - resolution: {integrity: sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-arm64@0.15.13: - resolution: {integrity: sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-arm@0.15.13: - resolution: {integrity: sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-mips64le@0.15.13: - resolution: {integrity: sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-ppc64le@0.15.13: - resolution: {integrity: sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-riscv64@0.15.13: - resolution: {integrity: sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-s390x@0.15.13: - resolution: {integrity: sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-netbsd-64@0.15.13: - resolution: {integrity: sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-openbsd-64@0.15.13: - resolution: {integrity: sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /esbuild-sunos-64@0.15.13: - resolution: {integrity: sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-32@0.15.13: - resolution: {integrity: sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-64@0.15.13: - resolution: {integrity: sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-arm64@0.15.13: - resolution: {integrity: sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /esbuild@0.15.13: - resolution: {integrity: sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.15.13 - '@esbuild/linux-loong64': 0.15.13 - esbuild-android-64: 0.15.13 - esbuild-android-arm64: 0.15.13 - esbuild-darwin-64: 0.15.13 - esbuild-darwin-arm64: 0.15.13 - esbuild-freebsd-64: 0.15.13 - esbuild-freebsd-arm64: 0.15.13 - esbuild-linux-32: 0.15.13 - esbuild-linux-64: 0.15.13 - esbuild-linux-arm: 0.15.13 - esbuild-linux-arm64: 0.15.13 - esbuild-linux-mips64le: 0.15.13 - esbuild-linux-ppc64le: 0.15.13 - esbuild-linux-riscv64: 0.15.13 - esbuild-linux-s390x: 0.15.13 - esbuild-netbsd-64: 0.15.13 - esbuild-openbsd-64: 0.15.13 - esbuild-sunos-64: 0.15.13 - esbuild-windows-32: 0.15.13 - esbuild-windows-64: 0.15.13 - esbuild-windows-arm64: 0.15.13 - dev: true - - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true - - /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.26.0)(eslint@8.23.0): - resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} - engines: {node: ^10.12.0 || >=12.0.0} - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.2 - dependencies: - confusing-browser-globals: 1.0.11 - eslint: 8.23.0 - eslint-plugin-import: 2.26.0(@typescript-eslint/parser@5.36.2)(eslint@8.23.0) - object.assign: 4.1.4 - object.entries: 1.1.5 - semver: 6.3.0 - dev: true - - /eslint-config-airbnb-typescript@17.0.0(@typescript-eslint/eslint-plugin@5.36.2)(@typescript-eslint/parser@5.36.2)(eslint-plugin-import@2.26.0)(eslint@8.23.0): - resolution: {integrity: sha512-elNiuzD0kPAPTXjFWg+lE24nMdHMtuxgYoD30OyMD6yrW1AhFZPAg27VX7d3tzOErw+dgJTNWfRSDqEcXb4V0g==} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.13.0 - '@typescript-eslint/parser': ^5.0.0 - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.3 - dependencies: - '@typescript-eslint/eslint-plugin': 5.36.2(@typescript-eslint/parser@5.36.2)(eslint@8.23.0)(typescript@4.8.2) - '@typescript-eslint/parser': 5.36.2(eslint@8.23.0)(typescript@4.8.2) - eslint: 8.23.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.26.0)(eslint@8.23.0) - eslint-plugin-import: 2.26.0(@typescript-eslint/parser@5.36.2)(eslint@8.23.0) - dev: true - - /eslint-config-prettier@8.5.0(eslint@8.23.0): - resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 8.23.0 - dev: true - - /eslint-import-resolver-node@0.3.6: - resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} - dependencies: - debug: 3.2.7 - resolve: 1.22.1 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-module-utils@2.7.4(@typescript-eslint/parser@5.36.2)(eslint-import-resolver-node@0.3.6)(eslint@8.23.0): - resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.36.2(eslint@8.23.0)(typescript@4.8.2) - debug: 3.2.7 - eslint: 8.23.0 - eslint-import-resolver-node: 0.3.6 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-plugin-import@2.26.0(@typescript-eslint/parser@5.36.2)(eslint@8.23.0): - resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 5.36.2(eslint@8.23.0)(typescript@4.8.2) - array-includes: 3.1.5 - array.prototype.flat: 1.3.1 - debug: 2.6.9 - doctrine: 2.1.0 - eslint: 8.23.0 - eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.36.2)(eslint-import-resolver-node@0.3.6)(eslint@8.23.0) - has: 1.0.3 - is-core-module: 2.11.0 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.values: 1.1.5 - resolve: 1.22.1 - tsconfig-paths: 3.14.1 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: true - - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true - - /eslint-scope@7.1.1: - resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - dev: true - - /eslint-utils@3.0.0(eslint@8.23.0): - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - dependencies: - eslint: 8.23.0 - eslint-visitor-keys: 2.1.0 - dev: true - - /eslint-visitor-keys@2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - dev: true - - /eslint-visitor-keys@3.3.0: - resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /eslint@8.23.0: - resolution: {integrity: sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint/eslintrc': 1.3.3 - '@humanwhocodes/config-array': 0.10.7 - '@humanwhocodes/gitignore-to-minimatch': 1.0.2 - '@humanwhocodes/module-importer': 1.0.1 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.1.1 - eslint-utils: 3.0.0(eslint@8.23.0) - eslint-visitor-keys: 3.3.0 - espree: 9.4.0 - esquery: 1.4.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - functional-red-black-tree: 1.0.1 - glob-parent: 6.0.2 - globals: 13.17.0 - globby: 11.1.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.0 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.1 - regexpp: 3.2.0 - strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - /espree@9.4.0: - resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.8.1 - acorn-jsx: 5.3.2(acorn@8.8.1) - eslint-visitor-keys: 3.3.0 - dev: true - - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /esquery@1.4.0: - resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - dev: true - - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - dev: true - - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true - - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true - - /events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - dev: true - - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true - - /expect@28.1.3: - resolution: {integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/expect-utils': 28.1.3 - jest-get-type: 28.0.2 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - dev: true - - /external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: true - - /extract-files@11.0.0: - resolution: {integrity: sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==} - engines: {node: ^12.20 || >= 14.13} - dev: true - - /extract-files@9.0.0: - resolution: {integrity: sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==} - engines: {node: ^10.17.0 || ^12.0.0 || >= 13.7.0} - dev: true - - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true - - /fast-glob@3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true - - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true - - /fastq@1.13.0: - resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} - dependencies: - reusify: 1.0.4 - dev: true - - /fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - dependencies: - bser: 2.1.1 - dev: true - - /fbjs-css-vars@1.0.2: - resolution: {integrity: sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==} - dev: true - - /fbjs@3.0.4: - resolution: {integrity: sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==} - dependencies: - cross-fetch: 3.1.5 - fbjs-css-vars: 1.0.2 - loose-envify: 1.4.0 - object-assign: 4.1.1 - promise: 7.3.1 - setimmediate: 1.0.5 - ua-parser-js: 0.7.33 - transitivePeerDependencies: - - encoding - dev: true - - /figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - dev: true - - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.0.4 - dev: true - - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - dev: true - - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - dev: true - - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - dev: true - - /follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /form-data@3.0.1: - resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: true - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} - dependencies: - graceful-fs: 4.2.10 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true - - /function.prototype.name@1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - functions-have-names: 1.2.3 - dev: true - - /functional-red-black-tree@1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - dev: true - - /functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true - - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic@1.1.3: - resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.3 - dev: true - - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true - - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true - - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - dev: true - - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - dev: true - - /glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - dev: true - - /glob@7.1.6: - resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - /globals@13.17.0: - resolution: {integrity: sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - dev: true - - /globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.12 - ignore: 5.2.0 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - - /graceful-fs@4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true - - /grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - dev: true - - /graphql-config@4.4.1(@types/node@18.6.2)(cosmiconfig-typescript-loader@4.3.0)(graphql@16.6.0): - resolution: {integrity: sha512-B8wlvfBHZ5WnI4IiuQZRqql6s+CKz7S+xpUeTb28Z8nRBi8tH9ChEBgT5FnTyE05PUhHlrS2jK9ICJ4YBl9OtQ==} - engines: {node: '>= 10.0.0'} - peerDependencies: - cosmiconfig-toml-loader: ^1.0.0 - cosmiconfig-typescript-loader: ^4.0.0 - graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - peerDependenciesMeta: - cosmiconfig-toml-loader: - optional: true - cosmiconfig-typescript-loader: - optional: true - dependencies: - '@graphql-tools/graphql-file-loader': 7.5.15(graphql@16.6.0) - '@graphql-tools/json-file-loader': 7.4.16(graphql@16.6.0) - '@graphql-tools/load': 7.8.11(graphql@16.6.0) - '@graphql-tools/merge': 8.3.17(graphql@16.6.0) - '@graphql-tools/url-loader': 7.17.9(@types/node@18.6.2)(graphql@16.6.0) - '@graphql-tools/utils': 9.2.0(graphql@16.6.0) - cosmiconfig: 8.0.0 - cosmiconfig-typescript-loader: 4.3.0(@types/node@18.6.2)(cosmiconfig@7.1.0)(ts-node@10.9.1)(typescript@4.8.2) - graphql: 16.6.0 - minimatch: 4.2.1 - string-env-interpolation: 1.0.1 - tslib: 2.5.0 - transitivePeerDependencies: - - '@types/node' - - bufferutil - - encoding - - utf-8-validate - dev: true - - /graphql-request@5.1.0(graphql@16.6.0): - resolution: {integrity: sha512-0OeRVYigVwIiXhNmqnPDt+JhMzsjinxHE7TVy3Lm6jUzav0guVcL0lfSbi6jVTRAxcbwgyr6yrZioSHxf9gHzw==} - peerDependencies: - graphql: 14 - 16 - dependencies: - '@graphql-typed-document-node/core': 3.1.1(graphql@16.6.0) - cross-fetch: 3.1.5 - extract-files: 9.0.0 - form-data: 3.0.1 - graphql: 16.6.0 - transitivePeerDependencies: - - encoding - dev: true - - /graphql-tag@2.12.6(graphql@16.6.0): - resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} - engines: {node: '>=10'} - peerDependencies: - graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - graphql: 16.6.0 - tslib: 2.5.0 - dev: true - - /graphql-ws@5.11.3(graphql@16.6.0): - resolution: {integrity: sha512-fU8zwSgAX2noXAsuFiCZ8BtXeXZOzXyK5u1LloCdacsVth4skdBMPO74EG51lBoWSIZ8beUocdpV8+cQHBODnQ==} - engines: {node: '>=10'} - peerDependencies: - graphql: '>=0.11 <=16' - dependencies: - graphql: 16.6.0 - dev: true - - /graphql@16.6.0: - resolution: {integrity: sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - dev: true - - /handlebars@4.7.7: - resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} - engines: {node: '>=0.4.7'} - hasBin: true - dependencies: - minimist: 1.2.7 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.17.4 - dev: true - - /has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true - - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} - dependencies: - get-intrinsic: 1.1.3 - dev: true - - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - dev: true - - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - dev: true - - /header-case@2.0.4: - resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} - dependencies: - capital-case: 1.0.4 - tslib: 2.5.0 - dev: true - - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - - /http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true - - /iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true - - /ignore@5.2.0: - resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} - engines: {node: '>= 4'} - dev: true - - /immutable@3.7.6: - resolution: {integrity: sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==} - engines: {node: '>=0.8.0'} - dev: true - - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - dev: true - - /import-from@4.0.0: - resolution: {integrity: sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==} - engines: {node: '>=12.2'} - dev: true - - /import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - dev: true - - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - - /indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - dev: true - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - /inquirer@8.2.5: - resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} - engines: {node: '>=12.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 7.0.0 - dev: true - - /internal-slot@1.0.3: - resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.1.3 - has: 1.0.3 - side-channel: 1.0.4 - dev: true - - /invariant@2.2.4: - resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} - dependencies: - loose-envify: 1.4.0 - dev: true - - /is-absolute@1.0.0: - resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} - engines: {node: '>=0.10.0'} - dependencies: - is-relative: 1.0.0 - is-windows: 1.0.2 - dev: true - - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - dependencies: - has-bigints: 1.0.2 - dev: true - - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - dependencies: - binary-extensions: 2.2.0 - dev: true - - /is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true - - /is-core-module@2.11.0: - resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} - dependencies: - has: 1.0.3 - dev: true - - /is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true - - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true - - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - dev: true - - /is-lower-case@2.0.2: - resolution: {integrity: sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==} - dependencies: - tslib: 2.5.0 - dev: true - - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} - engines: {node: '>= 0.4'} - dev: true - - /is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-relative@1.0.0: - resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} - engines: {node: '>=0.10.0'} - dependencies: - is-unc-path: 1.0.0 - dev: true - - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /is-unc-path@1.0.0: - resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} - engines: {node: '>=0.10.0'} - dependencies: - unc-path-regex: 0.1.2 - dev: true - - /is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - dev: true - - /is-upper-case@2.0.2: - resolution: {integrity: sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==} - dependencies: - tslib: 2.5.0 - dev: true - - /is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - /isomorphic-fetch@3.0.0: - resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} - dependencies: - node-fetch: 2.6.9 - whatwg-fetch: 3.6.2 - transitivePeerDependencies: - - encoding - dev: true - - /isomorphic-ws@5.0.0(ws@8.12.0): - resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} - peerDependencies: - ws: '*' - dependencies: - ws: 8.12.0 - dev: true - - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.19.6 - '@babel/parser': 7.20.1 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} - dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 - supports-color: 7.2.0 - dev: true - - /istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - dependencies: - debug: 4.3.4 - istanbul-lib-coverage: 3.2.0 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-reports@3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 - dev: true - - /jest-changed-files@28.1.3: - resolution: {integrity: sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - execa: 5.1.1 - p-limit: 3.1.0 - dev: true - - /jest-circus@28.1.3: - resolution: {integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/expect': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - chalk: 4.1.2 - co: 4.6.0 - dedent: 0.7.0 - is-generator-fn: 2.1.0 - jest-each: 28.1.3 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-runtime: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - p-limit: 3.1.0 - pretty-format: 28.1.3 - slash: 3.0.0 - stack-utils: 2.0.5 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-cli@28.1.3(@types/node@18.6.2)(ts-node@10.9.1): - resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 28.1.3(ts-node@10.9.1) - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.10 - import-local: 3.1.0 - jest-config: 28.1.3(@types/node@18.6.2)(ts-node@10.9.1) - jest-util: 28.1.3 - jest-validate: 28.1.3 - prompts: 2.4.2 - yargs: 17.6.2 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /jest-config@28.1.3(@types/node@18.6.2)(ts-node@10.9.1): - resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.19.6 - '@jest/test-sequencer': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - babel-jest: 28.1.3(@babel/core@7.19.6) - chalk: 4.1.2 - ci-info: 3.5.0 - deepmerge: 4.2.2 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-circus: 28.1.3 - jest-environment-node: 28.1.3 - jest-get-type: 28.0.2 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-runner: 28.1.3 - jest-util: 28.1.3 - jest-validate: 28.1.3 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 28.1.3 - slash: 3.0.0 - strip-json-comments: 3.1.1 - ts-node: 10.9.1(@types/node@18.6.2)(typescript@4.8.2) - transitivePeerDependencies: - - supports-color - dev: true - - /jest-diff@28.1.3: - resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - diff-sequences: 28.1.1 - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-docblock@28.1.1: - resolution: {integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - detect-newline: 3.1.0 - dev: true - - /jest-each@28.1.3: - resolution: {integrity: sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - chalk: 4.1.2 - jest-get-type: 28.0.2 - jest-util: 28.1.3 - pretty-format: 28.1.3 - dev: true - - /jest-environment-node@28.1.3: - resolution: {integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - jest-mock: 28.1.3 - jest-util: 28.1.3 - dev: true - - /jest-get-type@28.0.2: - resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /jest-haste-map@28.1.3: - resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/graceful-fs': 4.1.5 - '@types/node': 18.6.2 - anymatch: 3.1.2 - fb-watchman: 2.0.2 - graceful-fs: 4.2.10 - jest-regex-util: 28.0.2 - jest-util: 28.1.3 - jest-worker: 28.1.3 - micromatch: 4.0.5 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /jest-leak-detector@28.1.3: - resolution: {integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-matcher-utils@28.1.3: - resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - jest-diff: 28.1.3 - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-message-util@28.1.3: - resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/code-frame': 7.18.6 - '@jest/types': 28.1.3 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.10 - micromatch: 4.0.5 - pretty-format: 28.1.3 - slash: 3.0.0 - stack-utils: 2.0.5 - dev: true - - /jest-mock@28.1.3: - resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - dev: true - - /jest-pnp-resolver@1.2.2(jest-resolve@28.1.3): - resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 28.1.3 - dev: true - - /jest-regex-util@28.0.2: - resolution: {integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /jest-resolve-dependencies@28.1.3: - resolution: {integrity: sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-regex-util: 28.0.2 - jest-snapshot: 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-resolve@28.1.3: - resolution: {integrity: sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - jest-pnp-resolver: 1.2.2(jest-resolve@28.1.3) - jest-util: 28.1.3 - jest-validate: 28.1.3 - resolve: 1.22.1 - resolve.exports: 1.1.0 - slash: 3.0.0 - dev: true - - /jest-runner@28.1.3: - resolution: {integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/console': 28.1.3 - '@jest/environment': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - chalk: 4.1.2 - emittery: 0.10.2 - graceful-fs: 4.2.10 - jest-docblock: 28.1.1 - jest-environment-node: 28.1.3 - jest-haste-map: 28.1.3 - jest-leak-detector: 28.1.3 - jest-message-util: 28.1.3 - jest-resolve: 28.1.3 - jest-runtime: 28.1.3 - jest-util: 28.1.3 - jest-watcher: 28.1.3 - jest-worker: 28.1.3 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-runtime@28.1.3: - resolution: {integrity: sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/globals': 28.1.3 - '@jest/source-map': 28.1.2 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 - execa: 5.1.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - jest-message-util: 28.1.3 - jest-mock: 28.1.3 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-snapshot@28.1.3: - resolution: {integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/core': 7.19.6 - '@babel/generator': 7.20.1 - '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.19.6) - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.0 - '@jest/expect-utils': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/babel__traverse': 7.18.2 - '@types/prettier': 2.7.1 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.19.6) - chalk: 4.1.2 - expect: 28.1.3 - graceful-fs: 4.2.10 - jest-diff: 28.1.3 - jest-get-type: 28.0.2 - jest-haste-map: 28.1.3 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - natural-compare: 1.4.0 - pretty-format: 28.1.3 - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-util@28.1.3: - resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - chalk: 4.1.2 - ci-info: 3.5.0 - graceful-fs: 4.2.10 - picomatch: 2.3.1 - dev: true - - /jest-validate@28.1.3: - resolution: {integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 28.0.2 - leven: 3.1.0 - pretty-format: 28.1.3 - dev: true - - /jest-watcher@28.1.3: - resolution: {integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 18.6.2 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.10.2 - jest-util: 28.1.3 - string-length: 4.0.2 - dev: true - - /jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} - dependencies: - '@types/node': 18.6.2 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest-worker@28.1.3: - resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@types/node': 18.6.2 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest@28.1.3(@types/node@18.6.2)(ts-node@10.9.1): - resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 28.1.3(ts-node@10.9.1) - '@jest/types': 28.1.3 - import-local: 3.1.0 - jest-cli: 28.1.3(@types/node@18.6.2)(ts-node@10.9.1) - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - dev: true - - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true - - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - dev: true - - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true - - /json-schema-ref-parser@9.0.9: - resolution: {integrity: sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==} - engines: {node: '>=10'} - deprecated: Please switch to @apidevtools/json-schema-ref-parser - dependencies: - '@apidevtools/json-schema-ref-parser': 9.0.9 - dev: true - - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true - - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true - - /json-stable-stringify@1.0.2: - resolution: {integrity: sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==} - dependencies: - jsonify: 0.0.1 - dev: true - - /json-to-pretty-yaml@1.2.2: - resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==} - engines: {node: '>= 0.2.0'} - dependencies: - remedial: 1.0.8 - remove-trailing-spaces: 1.0.8 - dev: true - - /json5@1.0.1: - resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} - hasBin: true - dependencies: - minimist: 1.2.7 - dev: true - - /json5@2.2.1: - resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true - - /jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.10 - dev: true - - /jsonify@0.0.1: - resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} - dev: true - - /jsonwebtoken@9.0.0: - resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==} - engines: {node: '>=12', npm: '>=6'} - dependencies: - jws: 3.2.2 - lodash: 4.17.21 - ms: 2.1.3 - semver: 7.3.8 - dev: true - - /jwa@1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - dev: true - - /jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} - dependencies: - jwa: 1.4.1 - safe-buffer: 5.2.1 - dev: true - - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true - - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true - - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - /lilconfig@2.0.6: - resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} - engines: {node: '>=10'} - dev: true - - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true - - /listr2@4.0.5: - resolution: {integrity: sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==} - engines: {node: '>=12'} - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true - dependencies: - cli-truncate: 2.1.0 - colorette: 2.0.19 - log-update: 4.0.0 - p-map: 4.0.0 - rfdc: 1.3.0 - rxjs: 7.8.0 - through: 2.3.8 - wrap-ansi: 7.0.0 - dev: true - - /load-tsconfig@0.2.3: - resolution: {integrity: sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - - /loader-runner@4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} - engines: {node: '>=6.11.5'} - dev: true - - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - dev: true - - /lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - dev: true - - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true - - /lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - dev: true - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - - /log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - dev: true - - /log-update@4.0.0: - resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} - engines: {node: '>=10'} - dependencies: - ansi-escapes: 4.3.2 - cli-cursor: 3.1.0 - slice-ansi: 4.0.0 - wrap-ansi: 6.2.0 - dev: true - - /loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - dependencies: - js-tokens: 4.0.0 - dev: true - - /lower-case-first@2.0.2: - resolution: {integrity: sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==} - dependencies: - tslib: 2.5.0 - dev: true - - /lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - dependencies: - tslib: 2.5.0 - dev: true - - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - dev: true - - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: true - - /lunr@2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - dev: true - - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: true - - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - dependencies: - tmpl: 1.0.5 - dev: true - - /map-cache@0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - dev: true - - /marked@4.2.2: - resolution: {integrity: sha512-JjBTFTAvuTgANXx82a5vzK9JLSMoV6V3LBVn4Uhdso6t7vXrGx7g1Cd2r6NYSsxrYbQGFCMqBDhFHyK5q2UvcQ==} - engines: {node: '>= 12'} - hasBin: true - dev: true - - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true - - /meros@1.2.1(@types/node@18.6.2): - resolution: {integrity: sha512-R2f/jxYqCAGI19KhAvaxSOxALBMkaXWH2a7rOyqQw+ZmizX5bKkEYWLzdhC+U82ZVVPVp6MCXe3EkVligh+12g==} - engines: {node: '>=13'} - peerDependencies: - '@types/node': '>=13' - peerDependenciesMeta: - '@types/node': - optional: true - dependencies: - '@types/node': 18.6.2 - dev: true - - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - - /minimatch@4.2.1: - resolution: {integrity: sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 1.1.11 - dev: true - - /minimatch@5.1.0: - resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: true - - /minimist@1.2.7: - resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} - dev: true - - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: true - - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true - - /mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: true - - /mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - dev: true - - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true - - /neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - dev: true - - /no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - dependencies: - lower-case: 2.0.2 - tslib: 2.5.0 - dev: true - - /node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: true - - /node-fetch@2.6.9: - resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: true - - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true - - /node-releases@2.0.6: - resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} - dev: true - - /normalize-path@2.1.1: - resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} - engines: {node: '>=0.10.0'} - dependencies: - remove-trailing-separator: 1.1.0 - dev: true - - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true - - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - dev: true - - /nullthrows@1.1.1: - resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} - dev: true - - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: true - - /object-inspect@1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} - dev: true - - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true - - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true - - /object.entries@1.1.5: - resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /object.values@1.1.5: - resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - - /optionator@0.9.1: - resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.3 - dev: true - - /ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.7.0 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - dev: true - - /os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - dev: true - - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - dev: true - - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - dev: true - - /p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - dependencies: - aggregate-error: 3.1.0 - dev: true - - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /param-case@3.0.4: - resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} - dependencies: - dot-case: 3.0.4 - tslib: 2.5.0 - dev: true - - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - dev: true - - /parse-filepath@1.0.2: - resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} - engines: {node: '>=0.8'} - dependencies: - is-absolute: 1.0.0 - map-cache: 0.2.2 - path-root: 0.1.1 - dev: true - - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - dependencies: - '@babel/code-frame': 7.18.6 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - dev: true - - /pascal-case@3.1.2: - resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} - dependencies: - no-case: 3.0.4 - tslib: 2.5.0 - dev: true - - /path-case@3.0.4: - resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} - dependencies: - dot-case: 3.0.4 - tslib: 2.5.0 - dev: true - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true - - /path-root-regex@0.1.2: - resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} - engines: {node: '>=0.10.0'} - dev: true - - /path-root@0.1.1: - resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} - engines: {node: '>=0.10.0'} - dependencies: - path-root-regex: 0.1.2 - dev: true - - /path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true - - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - /pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - dev: true - - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /postcss-load-config@3.1.4(ts-node@10.9.1): - resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} - engines: {node: '>= 10'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - dependencies: - lilconfig: 2.0.6 - ts-node: 10.9.1(@types/node@18.6.2)(typescript@4.8.2) - yaml: 1.10.2 - dev: true - - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true - - /prettier@2.6.2: - resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true - - /pretty-format@28.1.3: - resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/schemas': 28.1.3 - ansi-regex: 5.0.1 - ansi-styles: 5.2.0 - react-is: 18.2.0 - dev: true - - /promise@7.3.1: - resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} - dependencies: - asap: 2.0.6 - dev: true - - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true - - /punycode@2.1.1: - resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} - engines: {node: '>=6'} - dev: true - - /pvtsutils@1.3.2: - resolution: {integrity: sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==} - dependencies: - tslib: 2.5.0 - dev: true - - /pvutils@1.1.3: - resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} - engines: {node: '>=6.0.0'} - dev: true - - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - /randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true - - /readable-stream@3.6.0: - resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} - engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: true - - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - dependencies: - picomatch: 2.3.1 - dev: true - - /regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: true - - /regexp.prototype.flags@1.4.3: - resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - functions-have-names: 1.2.3 - dev: true - - /regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - dev: true - - /relay-runtime@12.0.0: - resolution: {integrity: sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==} - dependencies: - '@babel/runtime': 7.20.13 - fbjs: 3.0.4 - invariant: 2.2.4 - transitivePeerDependencies: - - encoding - dev: true - - /remedial@1.0.8: - resolution: {integrity: sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==} - dev: true - - /remove-trailing-separator@1.1.0: - resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} - dev: true - - /remove-trailing-spaces@1.0.8: - resolution: {integrity: sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==} - dev: true - - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - dev: true - - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true - - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true - - /resolve.exports@1.1.0: - resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} - engines: {node: '>=10'} - dev: true - - /resolve@1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true - dependencies: - is-core-module: 2.11.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: true - - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - - /rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - dev: true - - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - - /rollup@2.79.1: - resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} - engines: {node: '>=10.0.0'} - hasBin: true - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: true - - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - dev: true - - /rxjs@7.8.0: - resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} - dependencies: - tslib: 2.5.0 - dev: true - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true - - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - is-regex: 1.1.4 - dev: true - - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true - - /schema-utils@3.1.2: - resolution: {integrity: sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==} - engines: {node: '>= 10.13.0'} - dependencies: - '@types/json-schema': 7.0.11 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) - dev: true - - /scuid@1.1.0: - resolution: {integrity: sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==} - dev: true - - /semver@6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - dev: true - - /semver@7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - - /sentence-case@3.0.4: - resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} - dependencies: - no-case: 3.0.4 - tslib: 2.5.0 - upper-case-first: 2.0.2 - dev: true - - /serialize-javascript@6.0.1: - resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} - dependencies: - randombytes: 2.1.0 - dev: true - - /set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: true - - /setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: true - - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true - - /shell-quote@1.8.0: - resolution: {integrity: sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==} - dev: true - - /shiki@0.11.1: - resolution: {integrity: sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==} - dependencies: - jsonc-parser: 3.2.0 - vscode-oniguruma: 1.6.2 - vscode-textmate: 6.0.0 - dev: true - - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - object-inspect: 1.12.2 - dev: true - - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true - - /signedsource@1.0.0: - resolution: {integrity: sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==} - dev: true - - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - /slice-ansi@3.0.0: - resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true - - /slice-ansi@4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true - - /snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - dependencies: - dot-case: 3.0.4 - tslib: 2.5.0 - dev: true - - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} - dependencies: - whatwg-url: 7.1.0 - dev: true - - /sponge-case@1.0.1: - resolution: {integrity: sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==} - dependencies: - tslib: 2.5.0 - dev: true - - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - - /stack-utils@2.0.5: - resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 - dev: true - - /streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - dev: true - - /string-env-interpolation@1.0.1: - resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==} - dev: true - - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - dev: true - - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: true - - /string.prototype.trimend@1.0.5: - resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /string.prototype.trimstart@1.0.5: - resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true - - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true - - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true - - /sucrase@3.28.0: - resolution: {integrity: sha512-TK9600YInjuiIhVM3729rH4ZKPOsGeyXUwY+Ugu9eilNbdTFyHr6XcAGYbRVZPDgWj6tgI7bx95aaJjHnbffag==} - engines: {node: '>=8'} - hasBin: true - dependencies: - commander: 4.1.1 - glob: 7.1.6 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.5 - ts-interface-checker: 0.1.13 - dev: true - - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true - - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-hyperlinks@2.3.0: - resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - dev: true - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true - - /swap-case@2.0.2: - resolution: {integrity: sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==} - dependencies: - tslib: 2.5.0 - dev: true - - /tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} - dev: true - - /terminal-link@2.1.1: - resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} - engines: {node: '>=8'} - dependencies: - ansi-escapes: 4.3.2 - supports-hyperlinks: 2.3.0 - dev: true - - /terser-webpack-plugin@5.3.7(esbuild@0.15.13)(webpack@5.80.0): - resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - esbuild: 0.15.13 - jest-worker: 27.5.1 - schema-utils: 3.1.2 - serialize-javascript: 6.0.1 - terser: 5.17.1 - webpack: 5.80.0(esbuild@0.15.13) - dev: true - - /terser@5.17.1: - resolution: {integrity: sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - '@jridgewell/source-map': 0.3.3 - acorn: 8.8.1 - commander: 2.20.3 - source-map-support: 0.5.21 - dev: true - - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true - - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true - - /thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - dependencies: - thenify: 3.3.1 - dev: true - - /thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - dependencies: - any-promise: 1.3.0 - dev: true - - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - - /title-case@3.0.3: - resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} - dependencies: - tslib: 2.5.0 - dev: true - - /tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: true - - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true - - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: true - - /tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - dependencies: - punycode: 2.1.1 - dev: true - - /tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - dev: true - - /ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - dev: true - - /ts-jest@28.0.8(@babel/core@7.19.6)(esbuild@0.15.13)(jest@28.1.3)(typescript@4.8.2): - resolution: {integrity: sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/types': ^28.0.0 - babel-jest: ^28.0.0 - esbuild: '*' - jest: ^28.0.0 - typescript: '>=4.3' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - dependencies: - '@babel/core': 7.19.6 - bs-logger: 0.2.6 - esbuild: 0.15.13 - fast-json-stable-stringify: 2.1.0 - jest: 28.1.3(@types/node@18.6.2)(ts-node@10.9.1) - jest-util: 28.1.3 - json5: 2.2.1 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.3.8 - typescript: 4.8.2 - yargs-parser: 21.1.1 - dev: true - - /ts-loader@9.3.1(typescript@4.8.2)(webpack@5.80.0): - resolution: {integrity: sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw==} - engines: {node: '>=12.0.0'} - peerDependencies: - typescript: '*' - webpack: ^5.0.0 - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.10.0 - micromatch: 4.0.5 - semver: 7.3.8 - typescript: 4.8.2 - webpack: 5.80.0(esbuild@0.15.13) - dev: true - - /ts-log@2.2.5: - resolution: {integrity: sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==} - dev: true - - /ts-node@10.9.1(@types/node@18.6.2)(typescript@4.8.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.3 - '@types/node': 18.6.2 - acorn: 8.8.1 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.8.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /tsconfig-paths@3.14.1: - resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.1 - minimist: 1.2.7 - strip-bom: 3.0.0 - dev: true - - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - - /tslib@2.4.1: - resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} - dev: true - - /tslib@2.5.0: - resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} - dev: true - - /tsup@6.2.3(ts-node@10.9.1)(typescript@4.8.2): - resolution: {integrity: sha512-J5Pu2Dx0E1wlpIEsVFv9ryzP1pZ1OYsJ2cBHZ7GrKteytNdzaSz5hmLX7/nAxtypq+jVkVvA79d7S83ETgHQ5w==} - engines: {node: '>=14'} - hasBin: true - peerDependencies: - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: ^4.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - dependencies: - bundle-require: 3.1.2(esbuild@0.15.13) - cac: 6.7.14 - chokidar: 3.5.3 - debug: 4.3.4 - esbuild: 0.15.13 - execa: 5.1.1 - globby: 11.1.0 - joycon: 3.1.1 - postcss-load-config: 3.1.4(ts-node@10.9.1) - resolve-from: 5.0.0 - rollup: 2.79.1 - source-map: 0.8.0-beta.0 - sucrase: 3.28.0 - tree-kill: 1.2.2 - typescript: 4.8.2 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - - /tsutils@3.21.0(typescript@4.8.2): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 4.8.2 - dev: true - - /tweetnacl@1.0.3: - resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - dev: false - - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - dev: true - - /type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true - - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true - - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true - - /typedoc@0.23.20(typescript@4.8.2): - resolution: {integrity: sha512-nfb4Mx05ZZZXux3zPcLuc7+3TVePDW3jTdEBqXdQzJUyEILxoprgPIiTChbvci9crkqNJG9YESmfCptuh9Gn3g==} - engines: {node: '>= 14.14'} - hasBin: true - peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x - dependencies: - lunr: 2.3.9 - marked: 4.2.2 - minimatch: 5.1.0 - shiki: 0.11.1 - typescript: 4.8.2 - dev: true - - /typescript@4.8.2: - resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /ua-parser-js@0.7.33: - resolution: {integrity: sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==} - dev: true - - /uglify-js@3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} - engines: {node: '>=0.8.0'} - hasBin: true - requiresBuild: true - dev: true - optional: true - - /unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - dependencies: - call-bind: 1.0.2 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - dev: true - - /unc-path-regex@0.1.2: - resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} - engines: {node: '>=0.10.0'} - dev: true - - /universalify@2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: true - - /unixify@1.0.0: - resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} - engines: {node: '>=0.10.0'} - dependencies: - normalize-path: 2.1.1 - dev: true - - /update-browserslist-db@1.0.10(browserslist@4.21.4): - resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.4 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true - - /upper-case-first@2.0.2: - resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} - dependencies: - tslib: 2.5.0 - dev: true - - /upper-case@2.0.2: - resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} - dependencies: - tslib: 2.5.0 - dev: true - - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.1.1 - dev: true - - /urlpattern-polyfill@6.0.2: - resolution: {integrity: sha512-5vZjFlH9ofROmuWmXM9yj2wljYKgWstGwe8YTyiqM7hVum/g9LyCizPZtb3UqsuppVwety9QJmfc42VggLpTgg==} - dependencies: - braces: 3.0.2 - dev: true - - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true - - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - - /v8-to-istanbul@9.0.1: - resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 - dev: true - - /value-or-promise@1.0.12: - resolution: {integrity: sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==} - engines: {node: '>=12'} - dev: true - - /vscode-oniguruma@1.6.2: - resolution: {integrity: sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==} - dev: true - - /vscode-textmate@6.0.0: - resolution: {integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==} - dev: true - - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - dependencies: - makeerror: 1.0.12 - dev: true - - /watchpack@2.4.0: - resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} - engines: {node: '>=10.13.0'} - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 - dev: true - - /wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - dependencies: - defaults: 1.0.4 - dev: true - - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: true - - /webcrypto-core@1.7.5: - resolution: {integrity: sha512-gaExY2/3EHQlRNNNVSrbG2Cg94Rutl7fAaKILS1w8ZDhGxdFOaw6EbCfHIxPy9vt/xwp5o0VQAx9aySPF6hU1A==} - dependencies: - '@peculiar/asn1-schema': 2.3.3 - '@peculiar/json-schema': 1.1.12 - asn1js: 3.0.5 - pvtsutils: 1.3.2 - tslib: 2.5.0 - dev: true - - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: true - - /webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - dev: true - - /webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} - engines: {node: '>=10.13.0'} - dev: true - - /webpack@5.80.0(esbuild@0.15.13): - resolution: {integrity: sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/eslint-scope': 3.7.4 - '@types/estree': 1.0.1 - '@webassemblyjs/ast': 1.11.5 - '@webassemblyjs/wasm-edit': 1.11.5 - '@webassemblyjs/wasm-parser': 1.11.5 - acorn: 8.8.1 - acorn-import-assertions: 1.8.0(acorn@8.8.1) - browserslist: 4.21.4 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.13.0 - es-module-lexer: 1.2.1 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.1.2 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.7(esbuild@0.15.13)(webpack@5.80.0) - watchpack: 2.4.0 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - dev: true - - /whatwg-fetch@3.6.2: - resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} - dev: true - - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: true - - /whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - dev: true - - /which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 - dev: true - - /which-module@2.0.0: - resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} - dev: true - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - /word-wrap@1.2.3: - resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} - engines: {node: '>=0.10.0'} - dev: true - - /wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - dev: true - - /wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - dev: true - - /ws@8.12.0: - resolution: {integrity: sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: true - - /y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - dev: true - - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true - - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true - - /yaml-ast-parser@0.0.43: - resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} - dev: true - - /yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} - dev: true - - /yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - dev: true - - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true - - /yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.0 - y18n: 4.0.3 - yargs-parser: 18.1.3 - dev: true - - /yargs@17.6.2: - resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} - engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: true - - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true - - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true - - '@github.com/aptos-labs/openapi-typescript-codegen/releases/download/v0.24.0-p1/openapi-typescript-codegen-v0.24.0-p1.tgz': - resolution: {tarball: https://github.com/aptos-labs/openapi-typescript-codegen/releases/download/v0.24.0-p1/openapi-typescript-codegen-v0.24.0-p1.tgz} - name: openapi-typescript-codegen - version: 0.24.0 - hasBin: true - dependencies: - camelcase: 6.3.0 - commander: 9.4.1 - fs-extra: 10.1.0 - handlebars: 4.7.7 - json-schema-ref-parser: 9.0.9 - dev: true diff --git a/m1/JavaScript-client/scripts/check.sh b/m1/JavaScript-client/scripts/check.sh deleted file mode 100644 index 456f83026..000000000 --- a/m1/JavaScript-client/scripts/check.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -# This script performs various validity checks prior to publishing a package -# to npm.js, such as checking the version and the changelog. - -set -e - -cd "$(dirname "$0")" -cd .. - -# Get the latest version of the package on npm.js -PUBLISHED_VERSION=`npm show aptos version` - -# Get the version from the local package.json file. -NEW_VERSION=`node -p -e "require('./package.json').version"` - -# Exit happily if the version is the same. -if [ "$NEW_VERSION" = "$PUBLISHED_VERSION" ]; then - echo "Version is the same. Exiting gracefully." - exit 0 -fi - -# Functions to help check if the version went backwards. -verlte() { - [ "$1" = "$(printf "$1\n$2" | sort -V | head -n1)" ] -} - -# Ensure the version didn't go backwards. -if verlte $NEW_VERSION $PUBLISHED_VERSION; then - echo "ERROR: The version number went backwards. Aborting." - exit 1 -fi - -# Ensure there is an entry for the new version in the changelog. -if ! grep -q "# $NEW_VERSION" CHANGELOG.md; then - echo "ERROR: The changelog does not contain an entry for the new version. Aborting." - exit 1 -fi - -echo "Version and changelog look good" diff --git a/m1/JavaScript-client/scripts/checked_publish.sh b/m1/JavaScript-client/scripts/checked_publish.sh deleted file mode 100644 index 62fdec1cd..000000000 --- a/m1/JavaScript-client/scripts/checked_publish.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -# This script publishes the package to npm.js, first perfoming validity checks. -# This script can be used locally or in CI safely. -# It assumes the package has already been installed, built, and tested. - -set -e - -cd "$(dirname "$0")" -cd .. - -# Make sure everything is valid. -. scripts/check.sh - -# Finally, publish the package. We assume it has been built -pnpm publish --non-interactive diff --git a/m1/JavaScript-client/scripts/generate_ts_docs.sh b/m1/JavaScript-client/scripts/generate_ts_docs.sh deleted file mode 100644 index 019920187..000000000 --- a/m1/JavaScript-client/scripts/generate_ts_docs.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -# This script helps you regenerate the TS docs at https://github.com/aptos-labs/ts-sdk-doc. - -DOCS_DIR=/tmp/ts-sdk-doc - -set -e - -cd "$(dirname "$0")" -cd .. - -# Generate the TS docs to a temporary directory. -rm -rf /tmp/generated-ts-docs -typedoc src/index.ts --out /tmp/generated-ts-docs - -# Clone the ts-sdk-doc repo. -rm -rf /tmp/ts-sdk-doc -git clone git@github.com:aptos-labs/ts-sdk-doc.git $DOCS_DIR - -# Copy the generated docs into the ts-sdk-doc repo. -rm -rf $DOCS_DIR/* -mv /tmp/generated-ts-docs/* $DOCS_DIR - -# Copy in a basic README -echo "# TS SDK Docs" > $DOCS_DIR/README.md -echo "" >> $DOCS_DIR/README.md -echo 'Generated from `ecosystem/typescript/sdk/` in [aptos-core](https://github.com/aptos-labs/aptos-core/tree/main/ecosystem/typescript/sdk) using `pnpm generate-ts-docs`.' >> $DOCS_DIR/README.md - -# Done! -echo -echo "Generated docs to $DOCS_DIR" -echo "From here, ensure that the changes look good. If so, copy the changes into a checkout of the ts-sdk-doc repo and make a PR!" diff --git a/m1/JavaScript-client/scripts/publish_ans_contract.ts b/m1/JavaScript-client/scripts/publish_ans_contract.ts deleted file mode 100644 index f851e13e7..000000000 --- a/m1/JavaScript-client/scripts/publish_ans_contract.ts +++ /dev/null @@ -1,63 +0,0 @@ -const { execSync } = require("child_process"); -require("dotenv").config(); - -/** - * TS SDK supports ANS. Since ANS contract is not part of aptos-framework - * we need to get the ANS contract, publish it to local testnet and test against it. - * This script clones the aptos-names-contracts repo {@link https://github.com/aptos-labs/aptos-names-contracts}, - * uses a pre created account address and private key to fund that account and - * then publish the contract under that account. - * After the contract is published, we delete the cloned repo folder. - * - * This script runs when testing locally and on CI (as part of sdk-release.yaml) using `pnpm test`. - */ - -// on local publishing we want to use `aptos` commnads and on CI we want to use `docker` -const APTOS_INVOCATION = process.env.APTOS_INVOCATION || "aptos"; -// environment we use when testing -const APTOS_NODE_URL = process.env.APTOS_NODE_URL; -const APTOS_FAUCET_URL = process.env.APTOS_FAUCET_URL; -// ans account we use to publish the contract -const ANS_REPO_LOCATION = process.env.ANS_REPO_LOCATION || "/tmp/ans"; -const ANS_TEST_ACCOUNT_PRIVATE_KEY = - process.env.ANS_TEST_ACCOUNT_PRIVATE_KEY || "0x37368b46ce665362562c6d1d4ec01a08c8644c488690df5a17e13ba163e20221"; -const ANS_TEST_ACCOUNT_ADDRESS = - process.env.ANS_TEST_ACCOUNT_ADDRESS || "585fc9f0f0c54183b039ffc770ca282ebd87307916c215a3e692f2f8e4305e82"; - -try { - deleteAnsFolder(); - // 1. Clone ANS repository into the current directory - console.log("---clone ANS repository---"); - execSync(`git clone https://github.com/aptos-labs/aptos-names-contracts.git ${ANS_REPO_LOCATION}`, { - stdio: "inherit", - }); - - // 2. fund ans account - console.log("---funding account---"); - execSync( - `${APTOS_INVOCATION} account fund-with-faucet --account ${ANS_TEST_ACCOUNT_ADDRESS} --faucet-url ${APTOS_FAUCET_URL} --url ${APTOS_NODE_URL}`, - { stdio: "inherit" }, - ); - - // 3. publish ans modules under the ans account - console.log("---publish ans modules---"); - execSync( - `${APTOS_INVOCATION} move publish --package-dir /tmp/ans/core --assume-yes --private-key=${ANS_TEST_ACCOUNT_PRIVATE_KEY} --named-addresses aptos_names=0x${ANS_TEST_ACCOUNT_ADDRESS},aptos_names_admin=0x${ANS_TEST_ACCOUNT_ADDRESS},aptos_names_funds=0x${ANS_TEST_ACCOUNT_ADDRESS} --url=${APTOS_NODE_URL}`, - { stdio: "inherit" }, - ); - - // 4. Delete aptos-names-contracts folder created by the git clone command - console.log("---module published, deleting aptos-names-contracts folder---"); - deleteAnsFolder(); -} catch (error: any) { - console.error("An error occurred:"); - console.error("Status", error?.status); - console.error("parsed stdout", error?.stdout?.toString("utf8")); - console.error("parsed stderr", error?.stderr?.toString("utf8")); - deleteAnsFolder(); - process.exit(1); -} - -function deleteAnsFolder() { - execSync("rm -rf /tmp/ans", { stdio: "inherit" }); -} diff --git a/m1/JavaScript-client/src/account/aptos_account.ts b/m1/JavaScript-client/src/account/aptos_account.ts deleted file mode 100644 index f7490f05b..000000000 --- a/m1/JavaScript-client/src/account/aptos_account.ts +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import nacl from "tweetnacl"; -import * as bip39 from "@scure/bip39"; -import { bytesToHex } from "@noble/hashes/utils"; -import { sha3_256 as sha3Hash } from "@noble/hashes/sha3"; -import { derivePath } from "../utils/hd-key"; -import { HexString, MaybeHexString, Memoize } from "../utils"; -import * as Gen from "../generated/index"; -import { AccountAddress, AuthenticationKey, Ed25519PublicKey } from "../aptos_types"; -import { bcsToBytes } from "../bcs"; - -export interface AptosAccountObject { - address?: Gen.HexEncodedBytes; - publicKeyHex?: Gen.HexEncodedBytes; - privateKeyHex: Gen.HexEncodedBytes; -} - -/** - * Class for creating and managing Aptos account - */ -export class AptosAccount { - /** - * A private key and public key, associated with the given account - */ - readonly signingKey: nacl.SignKeyPair; - - /** - * Address associated with the given account - */ - private readonly accountAddress: HexString; - - static fromAptosAccountObject(obj: AptosAccountObject): AptosAccount { - return new AptosAccount(HexString.ensure(obj.privateKeyHex).toUint8Array(), obj.address); - } - - /** - * Test derive path - */ - static isValidPath(path: string): boolean { - return /^m\/44'\/637'\/[0-9]+'\/[0-9]+'\/[0-9]+'+$/.test(path); - } - - /** - * Creates new account with bip44 path and mnemonics, - * @param path. (e.g. m/44'/637'/0'/0'/0') - * Detailed description: {@link https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki} - * @param mnemonics. - * @returns AptosAccount - */ - static fromDerivePath(path: string, mnemonics: string): AptosAccount { - if (!AptosAccount.isValidPath(path)) { - throw new Error("Invalid derivation path"); - } - - const normalizeMnemonics = mnemonics - .trim() - .split(/\s+/) - .map((part) => part.toLowerCase()) - .join(" "); - - const { key } = derivePath(path, bytesToHex(bip39.mnemonicToSeedSync(normalizeMnemonics))); - - return new AptosAccount(key); - } - - /** - * Creates new account instance. Constructor allows passing in an address, - * to handle account key rotation, where auth_key != public_key - * @param privateKeyBytes Private key from which account key pair will be generated. - * If not specified, new key pair is going to be created. - * @param address Account address (e.g. 0xe8012714cd17606cee7188a2a365eef3fe760be598750678c8c5954eb548a591). - * If not specified, a new one will be generated from public key - */ - constructor(privateKeyBytes?: Uint8Array | undefined, address?: MaybeHexString) { - if (privateKeyBytes) { - this.signingKey = nacl.sign.keyPair.fromSeed(privateKeyBytes.slice(0, 32)); - } else { - this.signingKey = nacl.sign.keyPair(); - } - this.accountAddress = HexString.ensure(address || this.authKey().hex()); - } - - /** - * This is the key by which Aptos account is referenced. - * It is the 32-byte of the SHA-3 256 cryptographic hash - * of the public key(s) concatenated with a signature scheme identifier byte - * @returns Address associated with the given account - */ - address(): HexString { - return this.accountAddress; - } - - /** - * This key enables account owners to rotate their private key(s) - * associated with the account without changing the address that hosts their account. - * See here for more info: {@link https://aptos.dev/concepts/accounts#single-signer-authentication} - * @returns Authentication key for the associated account - */ - @Memoize() - authKey(): HexString { - const pubKey = new Ed25519PublicKey(this.signingKey.publicKey); - const authKey = AuthenticationKey.fromEd25519PublicKey(pubKey); - return authKey.derivedAddress(); - } - - /** - * Takes source address and seeds and returns the resource account address - * @param sourceAddress Address used to derive the resource account - * @param seed The seed bytes - * @returns The resource account address - */ - - static getResourceAccountAddress(sourceAddress: MaybeHexString, seed: Uint8Array): HexString { - const source = bcsToBytes(AccountAddress.fromHex(sourceAddress)); - - const bytes = new Uint8Array([...source, ...seed, AuthenticationKey.DERIVE_RESOURCE_ACCOUNT_SCHEME]); - - const hash = sha3Hash.create(); - hash.update(bytes); - - return HexString.fromUint8Array(hash.digest()); - } - - /** - * This key is generated with Ed25519 scheme. - * Public key is used to check a signature of transaction, signed by given account - * @returns The public key for the associated account - */ - pubKey(): HexString { - return HexString.fromUint8Array(this.signingKey.publicKey); - } - - /** - * Signs specified `buffer` with account's private key - * @param buffer A buffer to sign - * @returns A signature HexString - */ - signBuffer(buffer: Uint8Array): HexString { - const signature = nacl.sign.detached(buffer, this.signingKey.secretKey); - return HexString.fromUint8Array(signature); - } - - /** - * Signs specified `hexString` with account's private key - * @param hexString A regular string or HexString to sign - * @returns A signature HexString - */ - signHexString(hexString: MaybeHexString): HexString { - const toSign = HexString.ensure(hexString).toUint8Array(); - return this.signBuffer(toSign); - } - - /** - * Verifies the signature of the message with the public key of the account - * @param message a signed message - * @param signature the signature of the message - */ - verifySignature(message: MaybeHexString, signature: MaybeHexString): boolean { - const rawMessage = HexString.ensure(message).toUint8Array(); - const rawSignature = HexString.ensure(signature).toUint8Array(); - return nacl.sign.detached.verify(rawMessage, rawSignature, this.signingKey.publicKey); - } - - /** - * Derives account address, public key and private key - * @returns AptosAccountObject instance. - * @example An example of the returned AptosAccountObject object - * ``` - * { - * address: "0xe8012714cd17606cee7188a2a365eef3fe760be598750678c8c5954eb548a591", - * publicKeyHex: "0xf56d8524faf79fbc0f48c13aeed3b0ce5dd376b4db93b8130a107c0a5e04ba04", - * privateKeyHex: `0x009c9f7c992a06cfafe916f125d8adb7a395fca243e264a8e56a4b3e6accf940 - * d2b11e9ece3049ce60e3c7b4a1c58aebfa9298e29a30a58a67f1998646135204` - * } - * ``` - */ - toPrivateKeyObject(): AptosAccountObject { - return { - address: this.address().hex(), - publicKeyHex: this.pubKey().hex(), - privateKeyHex: HexString.fromUint8Array(this.signingKey.secretKey.slice(0, 32)).hex(), - }; - } -} - -// Returns an account address as a HexString given either an AptosAccount or a MaybeHexString. -export function getAddressFromAccountOrAddress(accountOrAddress: AptosAccount | MaybeHexString): HexString { - return accountOrAddress instanceof AptosAccount ? accountOrAddress.address() : HexString.ensure(accountOrAddress); -} diff --git a/m1/JavaScript-client/src/account/index.ts b/m1/JavaScript-client/src/account/index.ts deleted file mode 100644 index 3af1a448c..000000000 --- a/m1/JavaScript-client/src/account/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./aptos_account"; diff --git a/m1/JavaScript-client/src/aptos_types/abi.ts b/m1/JavaScript-client/src/aptos_types/abi.ts deleted file mode 100644 index 1dd3ad23d..000000000 --- a/m1/JavaScript-client/src/aptos_types/abi.ts +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { Deserializer, Serializer, Bytes, Seq, deserializeVector, serializeVector } from "../bcs"; - -import { ModuleId } from "./transaction"; - -import { TypeTag } from "./type_tag"; - -export class TypeArgumentABI { - /** - * Constructs a TypeArgumentABI instance. - * @param name - */ - constructor(public readonly name: string) {} - - serialize(serializer: Serializer): void { - serializer.serializeStr(this.name); - } - - static deserialize(deserializer: Deserializer): TypeArgumentABI { - const name = deserializer.deserializeStr(); - return new TypeArgumentABI(name); - } -} - -export class ArgumentABI { - /** - * Constructs an ArgumentABI instance. - * @param name - * @param type_tag - */ - constructor(public readonly name: string, public readonly type_tag: TypeTag) {} - - serialize(serializer: Serializer): void { - serializer.serializeStr(this.name); - this.type_tag.serialize(serializer); - } - - static deserialize(deserializer: Deserializer): ArgumentABI { - const name = deserializer.deserializeStr(); - const typeTag = TypeTag.deserialize(deserializer); - return new ArgumentABI(name, typeTag); - } -} - -export abstract class ScriptABI { - abstract serialize(serializer: Serializer): void; - - static deserialize(deserializer: Deserializer): ScriptABI { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return TransactionScriptABI.load(deserializer); - case 1: - return EntryFunctionABI.load(deserializer); - default: - throw new Error(`Unknown variant index for TransactionPayload: ${index}`); - } - } -} - -export class TransactionScriptABI extends ScriptABI { - /** - * Constructs a TransactionScriptABI instance. - * @param name Entry function name - * @param doc - * @param code - * @param ty_args - * @param args - */ - constructor( - public readonly name: string, - public readonly doc: string, - public readonly code: Bytes, - public readonly ty_args: Seq, - public readonly args: Seq, - ) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(0); - serializer.serializeStr(this.name); - serializer.serializeStr(this.doc); - serializer.serializeBytes(this.code); - serializeVector(this.ty_args, serializer); - serializeVector(this.args, serializer); - } - - static load(deserializer: Deserializer): TransactionScriptABI { - const name = deserializer.deserializeStr(); - const doc = deserializer.deserializeStr(); - const code = deserializer.deserializeBytes(); - const tyArgs = deserializeVector(deserializer, TypeArgumentABI); - const args = deserializeVector(deserializer, ArgumentABI); - return new TransactionScriptABI(name, doc, code, tyArgs, args); - } -} - -export class EntryFunctionABI extends ScriptABI { - /** - * Constructs a EntryFunctionABI instance - * @param name - * @param module_name Fully qualified module id - * @param doc - * @param ty_args - * @param args - */ - constructor( - public readonly name: string, - public readonly module_name: ModuleId, - public readonly doc: string, - public readonly ty_args: Seq, - public readonly args: Seq, - ) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - serializer.serializeStr(this.name); - this.module_name.serialize(serializer); - serializer.serializeStr(this.doc); - serializeVector(this.ty_args, serializer); - serializeVector(this.args, serializer); - } - - static load(deserializer: Deserializer): EntryFunctionABI { - const name = deserializer.deserializeStr(); - const moduleName = ModuleId.deserialize(deserializer); - const doc = deserializer.deserializeStr(); - const tyArgs = deserializeVector(deserializer, TypeArgumentABI); - const args = deserializeVector(deserializer, ArgumentABI); - return new EntryFunctionABI(name, moduleName, doc, tyArgs, args); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/account_address.ts b/m1/JavaScript-client/src/aptos_types/account_address.ts deleted file mode 100644 index 3417f0d3d..000000000 --- a/m1/JavaScript-client/src/aptos_types/account_address.ts +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { HexString, MaybeHexString } from "../utils"; -import { Serializer, Deserializer, Bytes } from "../bcs"; - -export class AccountAddress { - static readonly LENGTH: number = 32; - - readonly address: Bytes; - - static CORE_CODE_ADDRESS: AccountAddress = AccountAddress.fromHex("0x1"); - - constructor(address: Bytes) { - if (address.length !== AccountAddress.LENGTH) { - throw new Error("Expected address of length 32"); - } - this.address = address; - } - - /** - * Creates AccountAddress from a hex string. - * @param addr Hex string can be with a prefix or without a prefix, - * e.g. '0x1aa' or '1aa'. Hex string will be left padded with 0s if too short. - */ - static fromHex(addr: MaybeHexString): AccountAddress { - let address = HexString.ensure(addr); - - // If an address hex has odd number of digits, padd the hex string with 0 - // e.g. '1aa' would become '01aa'. - if (address.noPrefix().length % 2 !== 0) { - address = new HexString(`0${address.noPrefix()}`); - } - - const addressBytes = address.toUint8Array(); - - if (addressBytes.length > AccountAddress.LENGTH) { - // eslint-disable-next-line quotes - throw new Error("Hex string is too long. Address's length is 32 bytes."); - } else if (addressBytes.length === AccountAddress.LENGTH) { - return new AccountAddress(addressBytes); - } - - const res: Bytes = new Uint8Array(AccountAddress.LENGTH); - res.set(addressBytes, AccountAddress.LENGTH - addressBytes.length); - - return new AccountAddress(res); - } - - /** - * Checks if the string is a valid AccountAddress - * @param addr Hex string can be with a prefix or without a prefix, - * e.g. '0x1aa' or '1aa'. Hex string will be left padded with 0s if too short. - */ - static isValid(addr: MaybeHexString): boolean { - // At least one zero is required - if (addr === "") { - return false; - } - - let address = HexString.ensure(addr); - - // If an address hex has odd number of digits, padd the hex string with 0 - // e.g. '1aa' would become '01aa'. - if (address.noPrefix().length % 2 !== 0) { - address = new HexString(`0${address.noPrefix()}`); - } - - const addressBytes = address.toUint8Array(); - - return addressBytes.length <= AccountAddress.LENGTH; - } - - /** - * Return a hex string from account Address. - */ - toHexString(): MaybeHexString { - return HexString.fromUint8Array(this.address).hex(); - } - - serialize(serializer: Serializer): void { - serializer.serializeFixedBytes(this.address); - } - - static deserialize(deserializer: Deserializer): AccountAddress { - return new AccountAddress(deserializer.deserializeFixedBytes(AccountAddress.LENGTH)); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/authentication_key.ts b/m1/JavaScript-client/src/aptos_types/authentication_key.ts deleted file mode 100644 index 74f9b7683..000000000 --- a/m1/JavaScript-client/src/aptos_types/authentication_key.ts +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { sha3_256 as sha3Hash } from "@noble/hashes/sha3"; -import { HexString } from "../utils"; -import { Bytes } from "../bcs"; -import { MultiEd25519PublicKey } from "./multi_ed25519"; -import { Ed25519PublicKey } from "./ed25519"; - -/** - * Each account stores an authentication key. Authentication key enables account owners to rotate - * their private key(s) associated with the account without changing the address that hosts their account. - * @see {@link * https://aptos.dev/concepts/accounts | Account Basics} - * - * Account addresses can be derived from AuthenticationKey - */ -export class AuthenticationKey { - static readonly LENGTH: number = 32; - - static readonly MULTI_ED25519_SCHEME: number = 1; - - static readonly ED25519_SCHEME: number = 0; - - static readonly DERIVE_RESOURCE_ACCOUNT_SCHEME: number = 255; - - readonly bytes: Bytes; - - constructor(bytes: Bytes) { - if (bytes.length !== AuthenticationKey.LENGTH) { - throw new Error("Expected a byte array of length 32"); - } - this.bytes = bytes; - } - - /** - * Converts a K-of-N MultiEd25519PublicKey to AuthenticationKey with: - * `auth_key = sha3-256(p_1 | … | p_n | K | 0x01)`. `K` represents the K-of-N required for - * authenticating the transaction. `0x01` is the 1-byte scheme for multisig. - */ - static fromMultiEd25519PublicKey(publicKey: MultiEd25519PublicKey): AuthenticationKey { - const pubKeyBytes = publicKey.toBytes(); - - const bytes = new Uint8Array(pubKeyBytes.length + 1); - bytes.set(pubKeyBytes); - bytes.set([AuthenticationKey.MULTI_ED25519_SCHEME], pubKeyBytes.length); - - const hash = sha3Hash.create(); - hash.update(bytes); - - return new AuthenticationKey(hash.digest()); - } - - static fromEd25519PublicKey(publicKey: Ed25519PublicKey): AuthenticationKey { - const pubKeyBytes = publicKey.value; - - const bytes = new Uint8Array(pubKeyBytes.length + 1); - bytes.set(pubKeyBytes); - bytes.set([AuthenticationKey.ED25519_SCHEME], pubKeyBytes.length); - - const hash = sha3Hash.create(); - hash.update(bytes); - - return new AuthenticationKey(hash.digest()); - } - - /** - * Derives an account address from AuthenticationKey. Since current AccountAddress is 32 bytes, - * AuthenticationKey bytes are directly translated to AccountAddress. - */ - derivedAddress(): HexString { - return HexString.fromUint8Array(this.bytes); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/authenticator.ts b/m1/JavaScript-client/src/aptos_types/authenticator.ts deleted file mode 100644 index ffbe57913..000000000 --- a/m1/JavaScript-client/src/aptos_types/authenticator.ts +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable @typescript-eslint/naming-convention */ -import { AccountAddress } from "./account_address"; -import { Serializer, Deserializer, Seq, deserializeVector, serializeVector } from "../bcs"; -import { Ed25519PublicKey, Ed25519Signature } from "./ed25519"; -import { MultiEd25519PublicKey, MultiEd25519Signature } from "./multi_ed25519"; - -export abstract class TransactionAuthenticator { - abstract serialize(serializer: Serializer): void; - - static deserialize(deserializer: Deserializer): TransactionAuthenticator { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return TransactionAuthenticatorEd25519.load(deserializer); - case 1: - return TransactionAuthenticatorMultiEd25519.load(deserializer); - case 2: - return TransactionAuthenticatorMultiAgent.load(deserializer); - default: - throw new Error(`Unknown variant index for TransactionAuthenticator: ${index}`); - } - } -} - -export class TransactionAuthenticatorEd25519 extends TransactionAuthenticator { - /** - * An authenticator for single signature. - * - * @param public_key Client's public key. - * @param signature Signature of a raw transaction. - * @see {@link https://aptos.dev/guides/creating-a-signed-transaction/ | Creating a Signed Transaction} - * for details about generating a signature. - */ - constructor(public readonly public_key: Ed25519PublicKey, public readonly signature: Ed25519Signature) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(0); - this.public_key.serialize(serializer); - this.signature.serialize(serializer); - } - - static load(deserializer: Deserializer): TransactionAuthenticatorEd25519 { - const public_key = Ed25519PublicKey.deserialize(deserializer); - const signature = Ed25519Signature.deserialize(deserializer); - return new TransactionAuthenticatorEd25519(public_key, signature); - } -} - -export class TransactionAuthenticatorMultiEd25519 extends TransactionAuthenticator { - /** - * An authenticator for multiple signatures. - * - * @param public_key - * @param signature - * - */ - constructor(public readonly public_key: MultiEd25519PublicKey, public readonly signature: MultiEd25519Signature) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - this.public_key.serialize(serializer); - this.signature.serialize(serializer); - } - - static load(deserializer: Deserializer): TransactionAuthenticatorMultiEd25519 { - const public_key = MultiEd25519PublicKey.deserialize(deserializer); - const signature = MultiEd25519Signature.deserialize(deserializer); - return new TransactionAuthenticatorMultiEd25519(public_key, signature); - } -} - -export class TransactionAuthenticatorMultiAgent extends TransactionAuthenticator { - constructor( - public readonly sender: AccountAuthenticator, - public readonly secondary_signer_addresses: Seq, - public readonly secondary_signers: Seq, - ) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(2); - this.sender.serialize(serializer); - serializeVector(this.secondary_signer_addresses, serializer); - serializeVector(this.secondary_signers, serializer); - } - - static load(deserializer: Deserializer): TransactionAuthenticatorMultiAgent { - const sender = AccountAuthenticator.deserialize(deserializer); - const secondary_signer_addresses = deserializeVector(deserializer, AccountAddress); - const secondary_signers = deserializeVector(deserializer, AccountAuthenticator); - return new TransactionAuthenticatorMultiAgent(sender, secondary_signer_addresses, secondary_signers); - } -} - -export abstract class AccountAuthenticator { - abstract serialize(serializer: Serializer): void; - - static deserialize(deserializer: Deserializer): AccountAuthenticator { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return AccountAuthenticatorEd25519.load(deserializer); - case 1: - return AccountAuthenticatorMultiEd25519.load(deserializer); - default: - throw new Error(`Unknown variant index for AccountAuthenticator: ${index}`); - } - } -} - -export class AccountAuthenticatorEd25519 extends AccountAuthenticator { - constructor(public readonly public_key: Ed25519PublicKey, public readonly signature: Ed25519Signature) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(0); - this.public_key.serialize(serializer); - this.signature.serialize(serializer); - } - - static load(deserializer: Deserializer): AccountAuthenticatorEd25519 { - const public_key = Ed25519PublicKey.deserialize(deserializer); - const signature = Ed25519Signature.deserialize(deserializer); - return new AccountAuthenticatorEd25519(public_key, signature); - } -} - -export class AccountAuthenticatorMultiEd25519 extends AccountAuthenticator { - constructor(public readonly public_key: MultiEd25519PublicKey, public readonly signature: MultiEd25519Signature) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - this.public_key.serialize(serializer); - this.signature.serialize(serializer); - } - - static load(deserializer: Deserializer): AccountAuthenticatorMultiEd25519 { - const public_key = MultiEd25519PublicKey.deserialize(deserializer); - const signature = MultiEd25519Signature.deserialize(deserializer); - return new AccountAuthenticatorMultiEd25519(public_key, signature); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/ed25519.ts b/m1/JavaScript-client/src/aptos_types/ed25519.ts deleted file mode 100644 index 1385e289e..000000000 --- a/m1/JavaScript-client/src/aptos_types/ed25519.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { Bytes, Deserializer, Serializer } from "../bcs"; - -export class Ed25519PublicKey { - static readonly LENGTH: number = 32; - - readonly value: Bytes; - - constructor(value: Bytes) { - if (value.length !== Ed25519PublicKey.LENGTH) { - throw new Error(`Ed25519PublicKey length should be ${Ed25519PublicKey.LENGTH}`); - } - this.value = value; - } - - toBytes(): Bytes { - return this.value; - } - - serialize(serializer: Serializer): void { - serializer.serializeBytes(this.value); - } - - static deserialize(deserializer: Deserializer): Ed25519PublicKey { - const value = deserializer.deserializeBytes(); - return new Ed25519PublicKey(value); - } -} - -export class Ed25519Signature { - static readonly LENGTH = 64; - - constructor(public readonly value: Bytes) { - if (value.length !== Ed25519Signature.LENGTH) { - throw new Error(`Ed25519Signature length should be ${Ed25519Signature.LENGTH}`); - } - } - - serialize(serializer: Serializer): void { - serializer.serializeBytes(this.value); - } - - static deserialize(deserializer: Deserializer): Ed25519Signature { - const value = deserializer.deserializeBytes(); - return new Ed25519Signature(value); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/identifier.ts b/m1/JavaScript-client/src/aptos_types/identifier.ts deleted file mode 100644 index 229f155f5..000000000 --- a/m1/JavaScript-client/src/aptos_types/identifier.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { Deserializer, Serializer } from "../bcs"; - -export class Identifier { - constructor(public value: string) {} - - public serialize(serializer: Serializer): void { - serializer.serializeStr(this.value); - } - - static deserialize(deserializer: Deserializer): Identifier { - const value = deserializer.deserializeStr(); - return new Identifier(value); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/index.ts b/m1/JavaScript-client/src/aptos_types/index.ts deleted file mode 100644 index 4c4ff9836..000000000 --- a/m1/JavaScript-client/src/aptos_types/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -export * from "./abi"; -export * from "./account_address"; -export * from "./authenticator"; -export * from "./transaction"; -export * from "./type_tag"; -export * from "./identifier"; -export * from "./ed25519"; -export * from "./multi_ed25519"; -export * from "./authentication_key"; -export * from "./rotation_proof_challenge"; - -export type SigningMessage = Uint8Array; diff --git a/m1/JavaScript-client/src/aptos_types/multi_ed25519.ts b/m1/JavaScript-client/src/aptos_types/multi_ed25519.ts deleted file mode 100644 index ad72c7a0b..000000000 --- a/m1/JavaScript-client/src/aptos_types/multi_ed25519.ts +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable no-bitwise */ -import { Bytes, Deserializer, Seq, Serializer, Uint8 } from "../bcs"; -import { Ed25519PublicKey, Ed25519Signature } from "./ed25519"; - -/** - * MultiEd25519 currently supports at most 32 signatures. - */ -const MAX_SIGNATURES_SUPPORTED = 32; - -export class MultiEd25519PublicKey { - /** - * Public key for a K-of-N multisig transaction. A K-of-N multisig transaction means that for such a - * transaction to be executed, at least K out of the N authorized signers have signed the transaction - * and passed the check conducted by the chain. - * - * @see {@link - * https://aptos.dev/guides/creating-a-signed-transaction#multisignature-transactions | Creating a Signed Transaction} - * - * @param public_keys A list of public keys - * @param threshold At least "threshold" signatures must be valid - */ - constructor(public readonly public_keys: Seq, public readonly threshold: Uint8) { - if (threshold > MAX_SIGNATURES_SUPPORTED) { - throw new Error(`"threshold" cannot be larger than ${MAX_SIGNATURES_SUPPORTED}`); - } - } - - /** - * Converts a MultiEd25519PublicKey into bytes with: bytes = p1_bytes | ... | pn_bytes | threshold - */ - toBytes(): Bytes { - const bytes = new Uint8Array(this.public_keys.length * Ed25519PublicKey.LENGTH + 1); - this.public_keys.forEach((k: Ed25519PublicKey, i: number) => { - bytes.set(k.value, i * Ed25519PublicKey.LENGTH); - }); - - bytes[this.public_keys.length * Ed25519PublicKey.LENGTH] = this.threshold; - - return bytes; - } - - serialize(serializer: Serializer): void { - serializer.serializeBytes(this.toBytes()); - } - - static deserialize(deserializer: Deserializer): MultiEd25519PublicKey { - const bytes = deserializer.deserializeBytes(); - const threshold = bytes[bytes.length - 1]; - - const keys: Seq = []; - - for (let i = 0; i < bytes.length - 1; i += Ed25519PublicKey.LENGTH) { - const begin = i; - keys.push(new Ed25519PublicKey(bytes.subarray(begin, begin + Ed25519PublicKey.LENGTH))); - } - return new MultiEd25519PublicKey(keys, threshold); - } -} - -export class MultiEd25519Signature { - static BITMAP_LEN: Uint8 = 4; - - /** - * Signature for a K-of-N multisig transaction. - * - * @see {@link - * https://aptos.dev/guides/creating-a-signed-transaction#multisignature-transactions | Creating a Signed Transaction} - * - * @param signatures A list of ed25519 signatures - * @param bitmap 4 bytes, at most 32 signatures are supported. If Nth bit value is `1`, the Nth - * signature should be provided in `signatures`. Bits are read from left to right - */ - constructor(public readonly signatures: Seq, public readonly bitmap: Uint8Array) { - if (bitmap.length !== MultiEd25519Signature.BITMAP_LEN) { - throw new Error(`"bitmap" length should be ${MultiEd25519Signature.BITMAP_LEN}`); - } - } - - /** - * Converts a MultiEd25519Signature into bytes with `bytes = s1_bytes | ... | sn_bytes | bitmap` - */ - toBytes(): Bytes { - const bytes = new Uint8Array(this.signatures.length * Ed25519Signature.LENGTH + MultiEd25519Signature.BITMAP_LEN); - this.signatures.forEach((k: Ed25519Signature, i: number) => { - bytes.set(k.value, i * Ed25519Signature.LENGTH); - }); - - bytes.set(this.bitmap, this.signatures.length * Ed25519Signature.LENGTH); - - return bytes; - } - - /** - * Helper method to create a bitmap out of the specified bit positions - * @param bits The bitmap positions that should be set. A position starts at index 0. - * Valid position should range between 0 and 31. - * @example - * Here's an example of valid `bits` - * ``` - * [0, 2, 31] - * ``` - * `[0, 2, 31]` means the 1st, 3rd and 32nd bits should be set in the bitmap. - * The result bitmap should be 0b1010000000000000000000000000001 - * - * @returns bitmap that is 32bit long - */ - static createBitmap(bits: Seq): Uint8Array { - // Bits are read from left to right. e.g. 0b10000000 represents the first bit is set in one byte. - // The decimal value of 0b10000000 is 128. - const firstBitInByte = 128; - const bitmap = new Uint8Array([0, 0, 0, 0]); - - // Check if duplicates exist in bits - const dupCheckSet = new Set(); - - bits.forEach((bit: number) => { - if (bit >= MAX_SIGNATURES_SUPPORTED) { - throw new Error(`Invalid bit value ${bit}.`); - } - - if (dupCheckSet.has(bit)) { - throw new Error("Duplicated bits detected."); - } - - dupCheckSet.add(bit); - - const byteOffset = Math.floor(bit / 8); - - let byte = bitmap[byteOffset]; - - byte |= firstBitInByte >> bit % 8; - - bitmap[byteOffset] = byte; - }); - - return bitmap; - } - - serialize(serializer: Serializer): void { - serializer.serializeBytes(this.toBytes()); - } - - static deserialize(deserializer: Deserializer): MultiEd25519Signature { - const bytes = deserializer.deserializeBytes(); - const bitmap = bytes.subarray(bytes.length - 4); - - const sigs: Seq = []; - - for (let i = 0; i < bytes.length - bitmap.length; i += Ed25519Signature.LENGTH) { - const begin = i; - sigs.push(new Ed25519Signature(bytes.subarray(begin, begin + Ed25519Signature.LENGTH))); - } - return new MultiEd25519Signature(sigs, bitmap); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/rotation_proof_challenge.ts b/m1/JavaScript-client/src/aptos_types/rotation_proof_challenge.ts deleted file mode 100644 index eb3b6942e..000000000 --- a/m1/JavaScript-client/src/aptos_types/rotation_proof_challenge.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AccountAddress } from "./account_address"; -import { Serializer } from "../bcs"; - -export class RotationProofChallenge { - constructor( - public readonly accountAddress: AccountAddress, - public readonly moduleName: string, - public readonly structName: string, - public readonly sequenceNumber: number | bigint, - public readonly originator: AccountAddress, - public readonly currentAuthKey: AccountAddress, - public readonly newPublicKey: Uint8Array, - ) {} - - serialize(serializer: Serializer): void { - this.accountAddress.serialize(serializer); - serializer.serializeStr(this.moduleName); - serializer.serializeStr(this.structName); - serializer.serializeU64(this.sequenceNumber); - this.originator.serialize(serializer); - this.currentAuthKey.serialize(serializer); - serializer.serializeBytes(this.newPublicKey); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/token_types.ts b/m1/JavaScript-client/src/aptos_types/token_types.ts deleted file mode 100644 index 3200c2bb3..000000000 --- a/m1/JavaScript-client/src/aptos_types/token_types.ts +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { deserializePropertyMap, PropertyMap, PropertyValue } from "../utils/property_map_serde"; - -export { PropertyMap, PropertyValue }; -export class TokenData { - /** Unique name within this creator's account for this Token's collection */ - collection: string; - - /** Description of Token */ - description: string; - - /** Name of Token */ - name: string; - - /** Optional maximum number of this Token */ - maximum?: number; - - /** Total number of this type of Token */ - supply: number; - - /** URL for additional information / media */ - uri: string; - - /** default properties of token data */ - default_properties: PropertyMap; - - /** mutability config of tokendata fields */ - mutability_config: boolean[]; - - constructor( - collection: string, - description: string, - name: string, - maximum: number, - supply: number, - uri: string, - default_properties: any, - mutability_config: boolean[], - ) { - this.collection = collection; - this.description = description; - this.name = name; - this.maximum = maximum; - this.supply = supply; - this.uri = uri; - this.default_properties = deserializePropertyMap(default_properties); - this.mutability_config = mutability_config; - } -} - -export interface TokenDataId { - /** Token creator address */ - creator: string; - - /** Unique name within this creator's account for this Token's collection */ - collection: string; - - /** Name of Token */ - name: string; -} - -export interface TokenId { - token_data_id: TokenDataId; - - /** version number of the property map */ - property_version: string; -} - -/** server will return string for u64 */ -type U64 = string; - -export class Token { - id: TokenId; - - /** server will return string for u64 */ - amount: U64; - - /** the property map of the token */ - token_properties: PropertyMap; - - constructor(id: TokenId, amount: U64, token_properties: any) { - this.id = id; - this.amount = amount; - this.token_properties = deserializePropertyMap(token_properties); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/transaction.ts b/m1/JavaScript-client/src/aptos_types/transaction.ts deleted file mode 100644 index c3d611dd5..000000000 --- a/m1/JavaScript-client/src/aptos_types/transaction.ts +++ /dev/null @@ -1,700 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable @typescript-eslint/naming-convention */ -/* eslint-disable class-methods-use-this */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable max-classes-per-file */ -import { sha3_256 as sha3Hash } from "@noble/hashes/sha3"; -import { HexString } from "../utils"; -import { - Deserializer, - Serializer, - Uint64, - Bytes, - Seq, - Uint8, - Uint128, - deserializeVector, - serializeVector, - bcsToBytes, - Uint16, - Uint256, -} from "../bcs"; -import { TransactionAuthenticator } from "./authenticator"; -import { Identifier } from "./identifier"; -import { TypeTag } from "./type_tag"; -import { AccountAddress } from "./account_address"; - -export class RawTransaction { - /** - * RawTransactions contain the metadata and payloads that can be submitted to Aptos chain for execution. - * RawTransactions must be signed before Aptos chain can execute them. - * - * @param sender Account address of the sender. - * @param sequence_number Sequence number of this transaction. This must match the sequence number stored in - * the sender's account at the time the transaction executes. - * @param payload Instructions for the Aptos Blockchain, including publishing a module, - * execute a entry function or execute a script payload. - * @param max_gas_amount Maximum total gas to spend for this transaction. The account must have more - * than this gas or the transaction will be discarded during validation. - * @param gas_unit_price Price to be paid per gas unit. - * @param expiration_timestamp_secs The blockchain timestamp at which the blockchain would discard this transaction. - * @param chain_id The chain ID of the blockchain that this transaction is intended to be run on. - */ - constructor( - public readonly sender: AccountAddress, - public readonly sequence_number: Uint64, - public readonly payload: TransactionPayload, - public readonly max_gas_amount: Uint64, - public readonly gas_unit_price: Uint64, - public readonly expiration_timestamp_secs: Uint64, - public readonly chain_id: ChainId, - ) {} - - serialize(serializer: Serializer): void { - this.sender.serialize(serializer); - serializer.serializeU64(this.sequence_number); - this.payload.serialize(serializer); - serializer.serializeU64(this.max_gas_amount); - serializer.serializeU64(this.gas_unit_price); - serializer.serializeU64(this.expiration_timestamp_secs); - this.chain_id.serialize(serializer); - } - - static deserialize(deserializer: Deserializer): RawTransaction { - const sender = AccountAddress.deserialize(deserializer); - const sequence_number = deserializer.deserializeU64(); - const payload = TransactionPayload.deserialize(deserializer); - const max_gas_amount = deserializer.deserializeU64(); - const gas_unit_price = deserializer.deserializeU64(); - const expiration_timestamp_secs = deserializer.deserializeU64(); - const chain_id = ChainId.deserialize(deserializer); - return new RawTransaction( - sender, - sequence_number, - payload, - max_gas_amount, - gas_unit_price, - expiration_timestamp_secs, - chain_id, - ); - } -} - -export class Script { - /** - * Scripts contain the Move bytecodes payload that can be submitted to Aptos chain for execution. - * @param code Move bytecode - * @param ty_args Type arguments that bytecode requires. - * - * @example - * A coin transfer function has one type argument "CoinType". - * ``` - * public(script) fun transfer(from: &signer, to: address, amount: u64,) - * ``` - * @param args Arugments to bytecode function. - * - * @example - * A coin transfer function has three arugments "from", "to" and "amount". - * ``` - * public(script) fun transfer(from: &signer, to: address, amount: u64,) - * ``` - */ - constructor( - public readonly code: Bytes, - public readonly ty_args: Seq, - public readonly args: Seq, - ) {} - - serialize(serializer: Serializer): void { - serializer.serializeBytes(this.code); - serializeVector(this.ty_args, serializer); - serializeVector(this.args, serializer); - } - - static deserialize(deserializer: Deserializer): Script { - const code = deserializer.deserializeBytes(); - const ty_args = deserializeVector(deserializer, TypeTag); - const args = deserializeVector(deserializer, TransactionArgument); - return new Script(code, ty_args, args); - } -} - -export class EntryFunction { - /** - * Contains the payload to run a function within a module. - * @param module_name Fully qualified module name. ModuleId consists of account address and module name. - * @param function_name The function to run. - * @param ty_args Type arguments that move function requires. - * - * @example - * A coin transfer function has one type argument "CoinType". - * ``` - * public(script) fun transfer(from: &signer, to: address, amount: u64,) - * ``` - * @param args Arugments to the move function. - * - * @example - * A coin transfer function has three arugments "from", "to" and "amount". - * ``` - * public(script) fun transfer(from: &signer, to: address, amount: u64,) - * ``` - */ - constructor( - public readonly module_name: ModuleId, - public readonly function_name: Identifier, - public readonly ty_args: Seq, - public readonly args: Seq, - ) {} - - /** - * - * @param module Fully qualified module name in format "AccountAddress::module_name" e.g. "0x1::coin" - * @param func Function name - * @param ty_args Type arguments that move function requires. - * - * @example - * A coin transfer function has one type argument "CoinType". - * ``` - * public(script) fun transfer(from: &signer, to: address, amount: u64,) - * ``` - * @param args Arugments to the move function. - * - * @example - * A coin transfer function has three arugments "from", "to" and "amount". - * ``` - * public(script) fun transfer(from: &signer, to: address, amount: u64,) - * ``` - * @returns - */ - static natural(module: string, func: string, ty_args: Seq, args: Seq): EntryFunction { - return new EntryFunction(ModuleId.fromStr(module), new Identifier(func), ty_args, args); - } - - /** - * `natual` is deprecated, please use `natural` - * - * @deprecated. - */ - static natual(module: string, func: string, ty_args: Seq, args: Seq): EntryFunction { - return EntryFunction.natural(module, func, ty_args, args); - } - - serialize(serializer: Serializer): void { - this.module_name.serialize(serializer); - this.function_name.serialize(serializer); - serializeVector(this.ty_args, serializer); - - serializer.serializeU32AsUleb128(this.args.length); - this.args.forEach((item: Bytes) => { - serializer.serializeBytes(item); - }); - } - - static deserialize(deserializer: Deserializer): EntryFunction { - const module_name = ModuleId.deserialize(deserializer); - const function_name = Identifier.deserialize(deserializer); - const ty_args = deserializeVector(deserializer, TypeTag); - - const length = deserializer.deserializeUleb128AsU32(); - const list: Seq = []; - for (let i = 0; i < length; i += 1) { - list.push(deserializer.deserializeBytes()); - } - - const args = list; - return new EntryFunction(module_name, function_name, ty_args, args); - } -} - -export class MultiSigTransactionPayload { - /** - * Contains the payload to run a multisig account transaction. - * @param transaction_payload The payload of the multisig transaction. This can only be EntryFunction for now but - * Script might be supported in the future. - */ - constructor(public readonly transaction_payload: EntryFunction) {} - - serialize(serializer: Serializer): void { - // We can support multiple types of inner transaction payload in the future. - // For now it's only EntryFunction but if we support more types, we need to serialize with the right enum values - // here - serializer.serializeU32AsUleb128(0); - this.transaction_payload.serialize(serializer); - } - - static deserialize(deserializer: Deserializer): MultiSigTransactionPayload { - // TODO: Support other types of payload beside EntryFunction. - // This is the enum value indicating which type of payload the multisig tx contains. - deserializer.deserializeUleb128AsU32(); - return new MultiSigTransactionPayload(EntryFunction.deserialize(deserializer)); - } -} - -export class MultiSig { - /** - * Contains the payload to run a multisig account transaction. - * @param multisig_address The multisig account address the transaction will be executed as. - * @param transaction_payload The payload of the multisig transaction. This is optional when executing a multisig - * transaction whose payload is already stored on chain. - */ - constructor( - public readonly multisig_address: AccountAddress, - public readonly transaction_payload?: MultiSigTransactionPayload, - ) {} - - serialize(serializer: Serializer): void { - this.multisig_address.serialize(serializer); - // Options are encoded with an extra u8 field before the value - 0x0 is none and 0x1 is present. - // We use serializeBool below to create this prefix value. - if (this.transaction_payload === undefined) { - serializer.serializeBool(false); - } else { - serializer.serializeBool(true); - this.transaction_payload.serialize(serializer); - } - } - - static deserialize(deserializer: Deserializer): MultiSig { - const multisig_address = AccountAddress.deserialize(deserializer); - const payloadPresent = deserializer.deserializeBool(); - let transaction_payload; - if (payloadPresent) { - transaction_payload = MultiSigTransactionPayload.deserialize(deserializer); - } - return new MultiSig(multisig_address, transaction_payload); - } -} - -export class Module { - /** - * Contains the bytecode of a Move module that can be published to the Aptos chain. - * @param code Move bytecode of a module. - */ - constructor(public readonly code: Bytes) {} - - serialize(serializer: Serializer): void { - serializer.serializeBytes(this.code); - } - - static deserialize(deserializer: Deserializer): Module { - const code = deserializer.deserializeBytes(); - return new Module(code); - } -} - -export class ModuleId { - /** - * Full name of a module. - * @param address The account address. - * @param name The name of the module under the account at "address". - */ - constructor(public readonly address: AccountAddress, public readonly name: Identifier) {} - - /** - * Converts a string literal to a ModuleId - * @param moduleId String literal in format "AccountAddress::module_name", - * e.g. "0x1::coin" - * @returns - */ - static fromStr(moduleId: string): ModuleId { - const parts = moduleId.split("::"); - if (parts.length !== 2) { - throw new Error("Invalid module id."); - } - return new ModuleId(AccountAddress.fromHex(new HexString(parts[0])), new Identifier(parts[1])); - } - - serialize(serializer: Serializer): void { - this.address.serialize(serializer); - this.name.serialize(serializer); - } - - static deserialize(deserializer: Deserializer): ModuleId { - const address = AccountAddress.deserialize(deserializer); - const name = Identifier.deserialize(deserializer); - return new ModuleId(address, name); - } -} - -export class ChangeSet { - serialize(serializer: Serializer): void { - throw new Error("Not implemented."); - } - - static deserialize(deserializer: Deserializer): ChangeSet { - throw new Error("Not implemented."); - } -} - -export class WriteSet { - serialize(serializer: Serializer): void { - throw new Error("Not implmented."); - } - - static deserialize(deserializer: Deserializer): WriteSet { - throw new Error("Not implmented."); - } -} - -export class SignedTransaction { - /** - * A SignedTransaction consists of a raw transaction and an authenticator. The authenticator - * contains a client's public key and the signature of the raw transaction. - * - * @see {@link https://aptos.dev/guides/creating-a-signed-transaction/ | Creating a Signed Transaction} - * - * @param raw_txn - * @param authenticator Contains a client's public key and the signature of the raw transaction. - * Authenticator has 3 flavors: single signature, multi-signature and multi-agent. - * @see authenticator.ts for details. - */ - constructor(public readonly raw_txn: RawTransaction, public readonly authenticator: TransactionAuthenticator) {} - - serialize(serializer: Serializer): void { - this.raw_txn.serialize(serializer); - this.authenticator.serialize(serializer); - } - - static deserialize(deserializer: Deserializer): SignedTransaction { - const raw_txn = RawTransaction.deserialize(deserializer); - const authenticator = TransactionAuthenticator.deserialize(deserializer); - return new SignedTransaction(raw_txn, authenticator); - } -} - -export abstract class RawTransactionWithData { - abstract serialize(serializer: Serializer): void; - - static deserialize(deserializer: Deserializer): RawTransactionWithData { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return MultiAgentRawTransaction.load(deserializer); - default: - throw new Error(`Unknown variant index for RawTransactionWithData: ${index}`); - } - } -} - -export class MultiAgentRawTransaction extends RawTransactionWithData { - constructor( - public readonly raw_txn: RawTransaction, - public readonly secondary_signer_addresses: Seq, - ) { - super(); - } - - serialize(serializer: Serializer): void { - // enum variant index - serializer.serializeU32AsUleb128(0); - this.raw_txn.serialize(serializer); - serializeVector(this.secondary_signer_addresses, serializer); - } - - static load(deserializer: Deserializer): MultiAgentRawTransaction { - const rawTxn = RawTransaction.deserialize(deserializer); - const secondarySignerAddresses = deserializeVector(deserializer, AccountAddress); - - return new MultiAgentRawTransaction(rawTxn, secondarySignerAddresses); - } -} - -export abstract class TransactionPayload { - abstract serialize(serializer: Serializer): void; - - static deserialize(deserializer: Deserializer): TransactionPayload { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return TransactionPayloadScript.load(deserializer); - // TODO: change to 1 once ModuleBundle has been removed from rust - case 2: - return TransactionPayloadEntryFunction.load(deserializer); - case 3: - return TransactionPayloadMultisig.load(deserializer); - default: - throw new Error(`Unknown variant index for TransactionPayload: ${index}`); - } - } -} - -export class TransactionPayloadScript extends TransactionPayload { - constructor(public readonly value: Script) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(0); - this.value.serialize(serializer); - } - - static load(deserializer: Deserializer): TransactionPayloadScript { - const value = Script.deserialize(deserializer); - return new TransactionPayloadScript(value); - } -} - -export class TransactionPayloadEntryFunction extends TransactionPayload { - constructor(public readonly value: EntryFunction) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(2); - this.value.serialize(serializer); - } - - static load(deserializer: Deserializer): TransactionPayloadEntryFunction { - const value = EntryFunction.deserialize(deserializer); - return new TransactionPayloadEntryFunction(value); - } -} - -export class TransactionPayloadMultisig extends TransactionPayload { - constructor(public readonly value: MultiSig) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(3); - this.value.serialize(serializer); - } - - static load(deserializer: Deserializer): TransactionPayloadMultisig { - const value = MultiSig.deserialize(deserializer); - return new TransactionPayloadMultisig(value); - } -} - -export class ChainId { - constructor(public readonly value: Uint8) {} - - serialize(serializer: Serializer): void { - serializer.serializeU8(this.value); - } - - static deserialize(deserializer: Deserializer): ChainId { - const value = deserializer.deserializeU8(); - return new ChainId(value); - } -} - -export abstract class TransactionArgument { - abstract serialize(serializer: Serializer): void; - - static deserialize(deserializer: Deserializer): TransactionArgument { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return TransactionArgumentU8.load(deserializer); - case 1: - return TransactionArgumentU64.load(deserializer); - case 2: - return TransactionArgumentU128.load(deserializer); - case 3: - return TransactionArgumentAddress.load(deserializer); - case 4: - return TransactionArgumentU8Vector.load(deserializer); - case 5: - return TransactionArgumentBool.load(deserializer); - case 6: - return TransactionArgumentU16.load(deserializer); - case 7: - return TransactionArgumentU32.load(deserializer); - case 8: - return TransactionArgumentU256.load(deserializer); - default: - throw new Error(`Unknown variant index for TransactionArgument: ${index}`); - } - } -} - -export class TransactionArgumentU8 extends TransactionArgument { - constructor(public readonly value: Uint8) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(0); - serializer.serializeU8(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentU8 { - const value = deserializer.deserializeU8(); - return new TransactionArgumentU8(value); - } -} - -export class TransactionArgumentU16 extends TransactionArgument { - constructor(public readonly value: Uint16) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(6); - serializer.serializeU16(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentU16 { - const value = deserializer.deserializeU16(); - return new TransactionArgumentU16(value); - } -} - -export class TransactionArgumentU32 extends TransactionArgument { - constructor(public readonly value: Uint16) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(7); - serializer.serializeU32(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentU32 { - const value = deserializer.deserializeU32(); - return new TransactionArgumentU32(value); - } -} - -export class TransactionArgumentU64 extends TransactionArgument { - constructor(public readonly value: Uint64) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - serializer.serializeU64(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentU64 { - const value = deserializer.deserializeU64(); - return new TransactionArgumentU64(value); - } -} - -export class TransactionArgumentU128 extends TransactionArgument { - constructor(public readonly value: Uint128) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(2); - serializer.serializeU128(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentU128 { - const value = deserializer.deserializeU128(); - return new TransactionArgumentU128(value); - } -} - -export class TransactionArgumentU256 extends TransactionArgument { - constructor(public readonly value: Uint256) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(8); - serializer.serializeU256(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentU256 { - const value = deserializer.deserializeU256(); - return new TransactionArgumentU256(value); - } -} - -export class TransactionArgumentAddress extends TransactionArgument { - constructor(public readonly value: AccountAddress) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(3); - this.value.serialize(serializer); - } - - static load(deserializer: Deserializer): TransactionArgumentAddress { - const value = AccountAddress.deserialize(deserializer); - return new TransactionArgumentAddress(value); - } -} - -export class TransactionArgumentU8Vector extends TransactionArgument { - constructor(public readonly value: Bytes) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(4); - serializer.serializeBytes(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentU8Vector { - const value = deserializer.deserializeBytes(); - return new TransactionArgumentU8Vector(value); - } -} - -export class TransactionArgumentBool extends TransactionArgument { - constructor(public readonly value: boolean) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(5); - serializer.serializeBool(this.value); - } - - static load(deserializer: Deserializer): TransactionArgumentBool { - const value = deserializer.deserializeBool(); - return new TransactionArgumentBool(value); - } -} - -export abstract class Transaction { - abstract serialize(serializer: Serializer): void; - - abstract hash(): Bytes; - - getHashSalt(): Bytes { - const hash = sha3Hash.create(); - hash.update("APTOS::Transaction"); - return hash.digest(); - } - - static deserialize(deserializer: Deserializer): Transaction { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return UserTransaction.load(deserializer); - default: - throw new Error(`Unknown variant index for Transaction: ${index}`); - } - } -} - -export class UserTransaction extends Transaction { - constructor(public readonly value: SignedTransaction) { - super(); - } - - hash(): Bytes { - const hash = sha3Hash.create(); - hash.update(this.getHashSalt()); - hash.update(bcsToBytes(this)); - return hash.digest(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(0); - this.value.serialize(serializer); - } - - static load(deserializer: Deserializer): UserTransaction { - return new UserTransaction(SignedTransaction.deserialize(deserializer)); - } -} diff --git a/m1/JavaScript-client/src/aptos_types/type_tag.ts b/m1/JavaScript-client/src/aptos_types/type_tag.ts deleted file mode 100644 index 293103605..000000000 --- a/m1/JavaScript-client/src/aptos_types/type_tag.ts +++ /dev/null @@ -1,458 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable class-methods-use-this */ -/* eslint-disable max-classes-per-file */ -import { AccountAddress } from "./account_address"; -import { Deserializer, Seq, Serializer, deserializeVector, serializeVector } from "../bcs"; -import { Identifier } from "./identifier"; - -export abstract class TypeTag { - abstract serialize(serializer: Serializer): void; - - static deserialize(deserializer: Deserializer): TypeTag { - const index = deserializer.deserializeUleb128AsU32(); - switch (index) { - case 0: - return TypeTagBool.load(deserializer); - case 1: - return TypeTagU8.load(deserializer); - case 2: - return TypeTagU64.load(deserializer); - case 3: - return TypeTagU128.load(deserializer); - case 4: - return TypeTagAddress.load(deserializer); - case 5: - return TypeTagSigner.load(deserializer); - case 6: - return TypeTagVector.load(deserializer); - case 7: - return TypeTagStruct.load(deserializer); - case 8: - return TypeTagU16.load(deserializer); - case 9: - return TypeTagU32.load(deserializer); - case 10: - return TypeTagU256.load(deserializer); - default: - throw new Error(`Unknown variant index for TypeTag: ${index}`); - } - } -} - -export class TypeTagBool extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(0); - } - - static load(deserializer: Deserializer): TypeTagBool { - return new TypeTagBool(); - } -} - -export class TypeTagU8 extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - } - - static load(_deserializer: Deserializer): TypeTagU8 { - return new TypeTagU8(); - } -} - -export class TypeTagU16 extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - } - - static load(_deserializer: Deserializer): TypeTagU16 { - return new TypeTagU16(); - } -} - -export class TypeTagU32 extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - } - - static load(_deserializer: Deserializer): TypeTagU32 { - return new TypeTagU32(); - } -} - -export class TypeTagU64 extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(2); - } - - static load(_deserializer: Deserializer): TypeTagU64 { - return new TypeTagU64(); - } -} - -export class TypeTagU128 extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(3); - } - - static load(_deserializer: Deserializer): TypeTagU128 { - return new TypeTagU128(); - } -} - -export class TypeTagU256 extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(1); - } - - static load(_deserializer: Deserializer): TypeTagU256 { - return new TypeTagU256(); - } -} - -export class TypeTagAddress extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(4); - } - - static load(_deserializer: Deserializer): TypeTagAddress { - return new TypeTagAddress(); - } -} - -export class TypeTagSigner extends TypeTag { - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(5); - } - - static load(_deserializer: Deserializer): TypeTagSigner { - return new TypeTagSigner(); - } -} - -export class TypeTagVector extends TypeTag { - constructor(public readonly value: TypeTag) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(6); - this.value.serialize(serializer); - } - - static load(deserializer: Deserializer): TypeTagVector { - const value = TypeTag.deserialize(deserializer); - return new TypeTagVector(value); - } -} - -export class TypeTagStruct extends TypeTag { - constructor(public readonly value: StructTag) { - super(); - } - - serialize(serializer: Serializer): void { - serializer.serializeU32AsUleb128(7); - this.value.serialize(serializer); - } - - static load(deserializer: Deserializer): TypeTagStruct { - const value = StructTag.deserialize(deserializer); - return new TypeTagStruct(value); - } - - isStringTypeTag(): boolean { - if ( - this.value.module_name.value === "string" && - this.value.name.value === "String" && - this.value.address.toHexString() === AccountAddress.fromHex("0x1").toHexString() - ) { - return true; - } - return false; - } -} - -export class StructTag { - constructor( - public readonly address: AccountAddress, - public readonly module_name: Identifier, - public readonly name: Identifier, - public readonly type_args: Seq, - ) {} - - /** - * Converts a string literal to a StructTag - * @param structTag String literal in format "AcountAddress::module_name::ResourceName", - * e.g. "0x1::aptos_coin::AptosCoin" - * @returns - */ - static fromString(structTag: string): StructTag { - // Use the TypeTagParser to parse the string literal into a TypeTagStruct - const typeTagStruct = new TypeTagParser(structTag).parseTypeTag() as TypeTagStruct; - - // Convert and return as a StructTag - return new StructTag( - typeTagStruct.value.address, - typeTagStruct.value.module_name, - typeTagStruct.value.name, - typeTagStruct.value.type_args, - ); - } - - serialize(serializer: Serializer): void { - this.address.serialize(serializer); - this.module_name.serialize(serializer); - this.name.serialize(serializer); - serializeVector(this.type_args, serializer); - } - - static deserialize(deserializer: Deserializer): StructTag { - const address = AccountAddress.deserialize(deserializer); - const moduleName = Identifier.deserialize(deserializer); - const name = Identifier.deserialize(deserializer); - const typeArgs = deserializeVector(deserializer, TypeTag); - return new StructTag(address, moduleName, name, typeArgs); - } -} - -export const stringStructTag = new StructTag( - AccountAddress.fromHex("0x1"), - new Identifier("string"), - new Identifier("String"), - [], -); - -function bail(message: string) { - throw new TypeTagParserError(message); -} - -function isWhiteSpace(c: string): boolean { - if (c.match(/\s/)) { - return true; - } - return false; -} - -function isValidAlphabetic(c: string): boolean { - if (c.match(/[_A-Za-z0-9]/g)) { - return true; - } - return false; -} - -// Generic format is T - for example T1, T2, T10 -function isGeneric(c: string): boolean { - if (c.match(/T\d+/g)) { - return true; - } - return false; -} - -type TokenType = string; -type TokenValue = string; -type Token = [TokenType, TokenValue]; - -// Returns Token and Token byte size -function nextToken(tagStr: string, pos: number): [Token, number] { - const c = tagStr[pos]; - if (c === ":") { - if (tagStr.slice(pos, pos + 2) === "::") { - return [["COLON", "::"], 2]; - } - bail("Unrecognized token."); - } else if (c === "<") { - return [["LT", "<"], 1]; - } else if (c === ">") { - return [["GT", ">"], 1]; - } else if (c === ",") { - return [["COMMA", ","], 1]; - } else if (isWhiteSpace(c)) { - let res = ""; - for (let i = pos; i < tagStr.length; i += 1) { - const char = tagStr[i]; - if (isWhiteSpace(char)) { - res = `${res}${char}`; - } else { - break; - } - } - return [["SPACE", res], res.length]; - } else if (isValidAlphabetic(c)) { - let res = ""; - for (let i = pos; i < tagStr.length; i += 1) { - const char = tagStr[i]; - if (isValidAlphabetic(char)) { - res = `${res}${char}`; - } else { - break; - } - } - if (isGeneric(res)) { - return [["GENERIC", res], res.length]; - } - return [["IDENT", res], res.length]; - } - throw new Error("Unrecognized token."); -} - -function tokenize(tagStr: string): Token[] { - let pos = 0; - const tokens = []; - while (pos < tagStr.length) { - const [token, size] = nextToken(tagStr, pos); - if (token[0] !== "SPACE") { - tokens.push(token); - } - pos += size; - } - return tokens; -} - -/** - * Parser to parse a type tag string - */ -export class TypeTagParser { - private readonly tokens: Token[]; - - private readonly typeTags: string[] = []; - - constructor(tagStr: string, typeTags?: string[]) { - this.tokens = tokenize(tagStr); - this.typeTags = typeTags || []; - } - - private consume(targetToken: string) { - const token = this.tokens.shift(); - if (!token || token[1] !== targetToken) { - bail("Invalid type tag."); - } - } - - private parseCommaList(endToken: TokenValue, allowTraillingComma: boolean): TypeTag[] { - const res: TypeTag[] = []; - if (this.tokens.length <= 0) { - bail("Invalid type tag."); - } - - while (this.tokens[0][1] !== endToken) { - res.push(this.parseTypeTag()); - - if (this.tokens.length > 0 && this.tokens[0][1] === endToken) { - break; - } - - this.consume(","); - if (this.tokens.length > 0 && this.tokens[0][1] === endToken && allowTraillingComma) { - break; - } - - if (this.tokens.length <= 0) { - bail("Invalid type tag."); - } - } - return res; - } - - parseTypeTag(): TypeTag { - if (this.tokens.length === 0) { - bail("Invalid type tag."); - } - - // Pop left most element out - const [tokenTy, tokenVal] = this.tokens.shift()!; - - if (tokenVal === "u8") { - return new TypeTagU8(); - } - if (tokenVal === "u16") { - return new TypeTagU16(); - } - if (tokenVal === "u32") { - return new TypeTagU32(); - } - if (tokenVal === "u64") { - return new TypeTagU64(); - } - if (tokenVal === "u128") { - return new TypeTagU128(); - } - if (tokenVal === "u256") { - return new TypeTagU256(); - } - if (tokenVal === "bool") { - return new TypeTagBool(); - } - if (tokenVal === "address") { - return new TypeTagAddress(); - } - if (tokenVal === "vector") { - this.consume("<"); - const res = this.parseTypeTag(); - this.consume(">"); - return new TypeTagVector(res); - } - if (tokenVal === "string") { - return new StructTag(AccountAddress.fromHex("0x1"), new Identifier("string"), new Identifier("String"), []); - } - if (tokenTy === "IDENT" && (tokenVal.startsWith("0x") || tokenVal.startsWith("0X"))) { - const address = tokenVal; - this.consume("::"); - const [moduleTokenTy, module] = this.tokens.shift()!; - if (moduleTokenTy !== "IDENT") { - bail("Invalid type tag."); - } - this.consume("::"); - const [nameTokenTy, name] = this.tokens.shift()!; - if (nameTokenTy !== "IDENT") { - bail("Invalid type tag."); - } - - // an Object `0x1::object::Object` doesn't hold a real type, it points to an address - // therefore, we parse it as an address and dont need to care/parse the `T` type - if (module === "object" && name === "Object") { - // to support a nested type tag, i.e 0x1::some_module::SomeResource<0x1::object::Object>, we want - // to remove the `` part from the tokens list so we dont parse it and can keep parse the type tag. - this.tokens.splice(0, 3); - return new TypeTagAddress(); - } - - let tyTags: TypeTag[] = []; - // Check if the struct has ty args - if (this.tokens.length > 0 && this.tokens[0][1] === "<") { - this.consume("<"); - tyTags = this.parseCommaList(">", true); - this.consume(">"); - } - - const structTag = new StructTag( - AccountAddress.fromHex(address), - new Identifier(module), - new Identifier(name), - tyTags, - ); - return new TypeTagStruct(structTag); - } - if (tokenTy === "GENERIC") { - if (this.typeTags.length === 0) { - bail("Can't convert generic type since no typeTags were specified."); - } - // a generic tokenVal has the format of `T`, for example `T1`. - // The digit (i.e 1) indicates the the index of this type in the typeTags array. - // For a tokenVal == T1, should be parsed as the type in typeTags[1] - const idx = parseInt(tokenVal.substring(1), 10); - return new TypeTagParser(this.typeTags[idx]).parseTypeTag(); - } - - throw new Error("Invalid type tag."); - } -} - -export class TypeTagParserError extends Error { - constructor(message: string) { - super(message); - this.name = "TypeTagParserError"; - } -} diff --git a/m1/JavaScript-client/src/bcs/consts.ts b/m1/JavaScript-client/src/bcs/consts.ts deleted file mode 100644 index 85ed2a8bf..000000000 --- a/m1/JavaScript-client/src/bcs/consts.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { Uint128, Uint16, Uint32, Uint64, Uint8, Uint256 } from "./types"; - -// Upper bound values for uint8, uint16, uint64 and uint128 -export const MAX_U8_NUMBER: Uint8 = 2 ** 8 - 1; -export const MAX_U16_NUMBER: Uint16 = 2 ** 16 - 1; -export const MAX_U32_NUMBER: Uint32 = 2 ** 32 - 1; -export const MAX_U64_BIG_INT: Uint64 = BigInt(2 ** 64) - BigInt(1); -export const MAX_U128_BIG_INT: Uint128 = BigInt(2 ** 128) - BigInt(1); -export const MAX_U256_BIG_INT: Uint256 = BigInt(2 ** 256) - BigInt(1); diff --git a/m1/JavaScript-client/src/bcs/deserializer.ts b/m1/JavaScript-client/src/bcs/deserializer.ts deleted file mode 100644 index 337011a63..000000000 --- a/m1/JavaScript-client/src/bcs/deserializer.ts +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable no-bitwise */ -import { MAX_U32_NUMBER } from "./consts"; -import { Bytes, Uint128, Uint16, Uint256, Uint32, Uint64, Uint8 } from "./types"; - -export class Deserializer { - private buffer: ArrayBuffer; - - private offset: number; - - constructor(data: Bytes) { - // copies data to prevent outside mutation of buffer. - this.buffer = new ArrayBuffer(data.length); - new Uint8Array(this.buffer).set(data, 0); - this.offset = 0; - } - - private read(length: number): ArrayBuffer { - if (this.offset + length > this.buffer.byteLength) { - throw new Error("Reached to the end of buffer"); - } - - const bytes = this.buffer.slice(this.offset, this.offset + length); - this.offset += length; - return bytes; - } - - /** - * Deserializes a string. UTF8 string is supported. Reads the string's bytes length "l" first, - * and then reads "l" bytes of content. Decodes the byte array into a string. - * - * BCS layout for "string": string_length | string_content. string_length is the bytes length of - * the string that is uleb128 encoded. string_length is a u32 integer. - * - * @example - * ```ts - * const deserializer = new Deserializer(new Uint8Array([24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, - * 0xe2, 0x89, 0xa0, 0xc2, 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, 0x88, 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab])); - * assert(deserializer.deserializeStr() === "çå∞≠¢õß∂ƒ∫"); - * ``` - */ - deserializeStr(): string { - const value = this.deserializeBytes(); - const textDecoder = new TextDecoder(); - return textDecoder.decode(value); - } - - /** - * Deserializes an array of bytes. - * - * BCS layout for "bytes": bytes_length | bytes. bytes_length is the length of the bytes array that is - * uleb128 encoded. bytes_length is a u32 integer. - */ - deserializeBytes(): Bytes { - const len = this.deserializeUleb128AsU32(); - return new Uint8Array(this.read(len)); - } - - /** - * Deserializes an array of bytes. The number of bytes to read is already known. - * - */ - deserializeFixedBytes(len: number): Bytes { - return new Uint8Array(this.read(len)); - } - - /** - * Deserializes a boolean value. - * - * BCS layout for "boolean": One byte. "0x01" for True and "0x00" for False. - */ - deserializeBool(): boolean { - const bool = new Uint8Array(this.read(1))[0]; - if (bool !== 1 && bool !== 0) { - throw new Error("Invalid boolean value"); - } - return bool === 1; - } - - /** - * Deserializes a uint8 number. - * - * BCS layout for "uint8": One byte. Binary format in little-endian representation. - */ - deserializeU8(): Uint8 { - return new DataView(this.read(1)).getUint8(0); - } - - /** - * Deserializes a uint16 number. - * - * BCS layout for "uint16": Two bytes. Binary format in little-endian representation. - * @example - * ```ts - * const deserializer = new Deserializer(new Uint8Array([0x34, 0x12])); - * assert(deserializer.deserializeU16() === 4660); - * ``` - */ - deserializeU16(): Uint16 { - return new DataView(this.read(2)).getUint16(0, true); - } - - /** - * Deserializes a uint32 number. - * - * BCS layout for "uint32": Four bytes. Binary format in little-endian representation. - * @example - * ```ts - * const deserializer = new Deserializer(new Uint8Array([0x78, 0x56, 0x34, 0x12])); - * assert(deserializer.deserializeU32() === 305419896); - * ``` - */ - deserializeU32(): Uint32 { - return new DataView(this.read(4)).getUint32(0, true); - } - - /** - * Deserializes a uint64 number. - * - * BCS layout for "uint64": Eight bytes. Binary format in little-endian representation. - * @example - * ```ts - * const deserializer = new Deserializer(new Uint8Array([0x00, 0xEF, 0xCD, 0xAB, 0x78, 0x56, 0x34, 0x12])); - * assert(deserializer.deserializeU64() === 1311768467750121216); - * ``` - */ - deserializeU64(): Uint64 { - const low = this.deserializeU32(); - const high = this.deserializeU32(); - - // combine the two 32-bit values and return (little endian) - return BigInt((BigInt(high) << BigInt(32)) | BigInt(low)); - } - - /** - * Deserializes a uint128 number. - * - * BCS layout for "uint128": Sixteen bytes. Binary format in little-endian representation. - */ - deserializeU128(): Uint128 { - const low = this.deserializeU64(); - const high = this.deserializeU64(); - - // combine the two 64-bit values and return (little endian) - return BigInt((high << BigInt(64)) | low); - } - - /** - * Deserializes a uint256 number. - * - * BCS layout for "uint256": Thirty-two bytes. Binary format in little-endian representation. - */ - deserializeU256(): Uint256 { - const low = this.deserializeU128(); - const high = this.deserializeU128(); - - // combine the two 128-bit values and return (little endian) - return BigInt((high << BigInt(128)) | low); - } - - /** - * Deserializes a uleb128 encoded uint32 number. - * - * BCS use uleb128 encoding in two cases: (1) lengths of variable-length sequences and (2) tags of enum values - */ - deserializeUleb128AsU32(): Uint32 { - let value: bigint = BigInt(0); - let shift = 0; - - while (value < MAX_U32_NUMBER) { - const byte = this.deserializeU8(); - value |= BigInt(byte & 0x7f) << BigInt(shift); - - if ((byte & 0x80) === 0) { - break; - } - shift += 7; - } - - if (value > MAX_U32_NUMBER) { - throw new Error("Overflow while parsing uleb128-encoded uint32 value"); - } - - return Number(value); - } -} diff --git a/m1/JavaScript-client/src/bcs/helper.ts b/m1/JavaScript-client/src/bcs/helper.ts deleted file mode 100644 index 21059c0ae..000000000 --- a/m1/JavaScript-client/src/bcs/helper.ts +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { Deserializer } from "./deserializer"; -import { Serializer } from "./serializer"; -import { AnyNumber, Bytes, Seq, Uint16, Uint32, Uint8 } from "./types"; - -interface Serializable { - serialize(serializer: Serializer): void; -} - -/** - * Serializes a vector values that are "Serializable". - */ -export function serializeVector(value: Seq, serializer: Serializer): void { - serializer.serializeU32AsUleb128(value.length); - value.forEach((item: T) => { - item.serialize(serializer); - }); -} - -/** - * Serializes a vector with specified item serialization function. - * Very dynamic function and bypasses static typechecking. - */ -export function serializeVectorWithFunc(value: any[], func: string): Bytes { - const serializer = new Serializer(); - serializer.serializeU32AsUleb128(value.length); - const f = (serializer as any)[func]; - value.forEach((item) => { - f.call(serializer, item); - }); - return serializer.getBytes(); -} - -/** - * Deserializes a vector of values. - */ -export function deserializeVector(deserializer: Deserializer, cls: any): any[] { - const length = deserializer.deserializeUleb128AsU32(); - const list: Seq = []; - for (let i = 0; i < length; i += 1) { - list.push(cls.deserialize(deserializer)); - } - return list; -} - -export function bcsToBytes(value: T): Bytes { - const serializer = new Serializer(); - value.serialize(serializer); - return serializer.getBytes(); -} - -export function bcsSerializeUint64(value: AnyNumber): Bytes { - const serializer = new Serializer(); - serializer.serializeU64(value); - return serializer.getBytes(); -} - -export function bcsSerializeU8(value: Uint8): Bytes { - const serializer = new Serializer(); - serializer.serializeU8(value); - return serializer.getBytes(); -} - -export function bcsSerializeU16(value: Uint16): Bytes { - const serializer = new Serializer(); - serializer.serializeU16(value); - return serializer.getBytes(); -} - -export function bcsSerializeU32(value: Uint32): Bytes { - const serializer = new Serializer(); - serializer.serializeU32(value); - return serializer.getBytes(); -} - -export function bcsSerializeU128(value: AnyNumber): Bytes { - const serializer = new Serializer(); - serializer.serializeU128(value); - return serializer.getBytes(); -} - -export function bcsSerializeBool(value: boolean): Bytes { - const serializer = new Serializer(); - serializer.serializeBool(value); - return serializer.getBytes(); -} - -export function bcsSerializeStr(value: string): Bytes { - const serializer = new Serializer(); - serializer.serializeStr(value); - return serializer.getBytes(); -} - -export function bcsSerializeBytes(value: Bytes): Bytes { - const serializer = new Serializer(); - serializer.serializeBytes(value); - return serializer.getBytes(); -} - -export function bcsSerializeFixedBytes(value: Bytes): Bytes { - const serializer = new Serializer(); - serializer.serializeFixedBytes(value); - return serializer.getBytes(); -} diff --git a/m1/JavaScript-client/src/bcs/index.ts b/m1/JavaScript-client/src/bcs/index.ts deleted file mode 100644 index db399051d..000000000 --- a/m1/JavaScript-client/src/bcs/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -export * from "./types"; -export * from "./serializer"; -export * from "./deserializer"; -export * from "./helper"; diff --git a/m1/JavaScript-client/src/bcs/serializer.ts b/m1/JavaScript-client/src/bcs/serializer.ts deleted file mode 100644 index b60bdbb66..000000000 --- a/m1/JavaScript-client/src/bcs/serializer.ts +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable no-bitwise */ -import { - MAX_U128_BIG_INT, - MAX_U16_NUMBER, - MAX_U32_NUMBER, - MAX_U64_BIG_INT, - MAX_U8_NUMBER, - MAX_U256_BIG_INT, -} from "./consts"; -import { AnyNumber, Bytes, Uint16, Uint32, Uint8 } from "./types"; - -export class Serializer { - private buffer: ArrayBuffer; - - private offset: number; - - constructor() { - this.buffer = new ArrayBuffer(64); - this.offset = 0; - } - - private ensureBufferWillHandleSize(bytes: number) { - while (this.buffer.byteLength < this.offset + bytes) { - const newBuffer = new ArrayBuffer(this.buffer.byteLength * 2); - new Uint8Array(newBuffer).set(new Uint8Array(this.buffer)); - this.buffer = newBuffer; - } - } - - protected serialize(values: Bytes) { - this.ensureBufferWillHandleSize(values.length); - new Uint8Array(this.buffer, this.offset).set(values); - this.offset += values.length; - } - - private serializeWithFunction( - fn: (byteOffset: number, value: number, littleEndian?: boolean) => void, - bytesLength: number, - value: number, - ) { - this.ensureBufferWillHandleSize(bytesLength); - const dv = new DataView(this.buffer, this.offset); - fn.apply(dv, [0, value, true]); - this.offset += bytesLength; - } - - /** - * Serializes a string. UTF8 string is supported. Serializes the string's bytes length "l" first, - * and then serializes "l" bytes of the string content. - * - * BCS layout for "string": string_length | string_content. string_length is the bytes length of - * the string that is uleb128 encoded. string_length is a u32 integer. - * - * @example - * ```ts - * const serializer = new Serializer(); - * serializer.serializeStr("çå∞≠¢õß∂ƒ∫"); - * assert(serializer.getBytes() === new Uint8Array([24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, - * 0xe2, 0x89, 0xa0, 0xc2, 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, 0x88, 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab])); - * ``` - */ - serializeStr(value: string): void { - const textEncoder = new TextEncoder(); - this.serializeBytes(textEncoder.encode(value)); - } - - /** - * Serializes an array of bytes. - * - * BCS layout for "bytes": bytes_length | bytes. bytes_length is the length of the bytes array that is - * uleb128 encoded. bytes_length is a u32 integer. - */ - serializeBytes(value: Bytes): void { - this.serializeU32AsUleb128(value.length); - this.serialize(value); - } - - /** - * Serializes an array of bytes with known length. Therefore length doesn't need to be - * serialized to help deserialization. When deserializing, the number of - * bytes to deserialize needs to be passed in. - */ - serializeFixedBytes(value: Bytes): void { - this.serialize(value); - } - - /** - * Serializes a boolean value. - * - * BCS layout for "boolean": One byte. "0x01" for True and "0x00" for False. - */ - serializeBool(value: boolean): void { - if (typeof value !== "boolean") { - throw new Error("Value needs to be a boolean"); - } - const byteValue = value ? 1 : 0; - this.serialize(new Uint8Array([byteValue])); - } - - /** - * Serializes a uint8 number. - * - * BCS layout for "uint8": One byte. Binary format in little-endian representation. - */ - @checkNumberRange(0, MAX_U8_NUMBER) - serializeU8(value: Uint8): void { - this.serialize(new Uint8Array([value])); - } - - /** - * Serializes a uint16 number. - * - * BCS layout for "uint16": Two bytes. Binary format in little-endian representation. - * @example - * ```ts - * const serializer = new Serializer(); - * serializer.serializeU16(4660); - * assert(serializer.getBytes() === new Uint8Array([0x34, 0x12])); - * ``` - */ - @checkNumberRange(0, MAX_U16_NUMBER) - serializeU16(value: Uint16): void { - this.serializeWithFunction(DataView.prototype.setUint16, 2, value); - } - - /** - * Serializes a uint32 number. - * - * BCS layout for "uint32": Four bytes. Binary format in little-endian representation. - * @example - * ```ts - * const serializer = new Serializer(); - * serializer.serializeU32(305419896); - * assert(serializer.getBytes() === new Uint8Array([0x78, 0x56, 0x34, 0x12])); - * ``` - */ - @checkNumberRange(0, MAX_U32_NUMBER) - serializeU32(value: Uint32): void { - this.serializeWithFunction(DataView.prototype.setUint32, 4, value); - } - - /** - * Serializes a uint64 number. - * - * BCS layout for "uint64": Eight bytes. Binary format in little-endian representation. - * @example - * ```ts - * const serializer = new Serializer(); - * serializer.serializeU64(1311768467750121216); - * assert(serializer.getBytes() === new Uint8Array([0x00, 0xEF, 0xCD, 0xAB, 0x78, 0x56, 0x34, 0x12])); - * ``` - */ - @checkNumberRange(BigInt(0), MAX_U64_BIG_INT) - serializeU64(value: AnyNumber): void { - const low = BigInt(value.toString()) & BigInt(MAX_U32_NUMBER); - const high = BigInt(value.toString()) >> BigInt(32); - - // write little endian number - this.serializeU32(Number(low)); - this.serializeU32(Number(high)); - } - - /** - * Serializes a uint128 number. - * - * BCS layout for "uint128": Sixteen bytes. Binary format in little-endian representation. - */ - @checkNumberRange(BigInt(0), MAX_U128_BIG_INT) - serializeU128(value: AnyNumber): void { - const low = BigInt(value.toString()) & MAX_U64_BIG_INT; - const high = BigInt(value.toString()) >> BigInt(64); - - // write little endian number - this.serializeU64(low); - this.serializeU64(high); - } - - /** - * Serializes a uint256 number. - * - * BCS layout for "uint256": Sixteen bytes. Binary format in little-endian representation. - */ - @checkNumberRange(BigInt(0), MAX_U256_BIG_INT) - serializeU256(value: AnyNumber): void { - const low = BigInt(value.toString()) & MAX_U128_BIG_INT; - const high = BigInt(value.toString()) >> BigInt(128); - - // write little endian number - this.serializeU128(low); - this.serializeU128(high); - } - - /** - * Serializes a uint32 number with uleb128. - * - * BCS use uleb128 encoding in two cases: (1) lengths of variable-length sequences and (2) tags of enum values - */ - @checkNumberRange(0, MAX_U32_NUMBER) - serializeU32AsUleb128(val: Uint32): void { - let value = val; - const valueArray = []; - while (value >>> 7 !== 0) { - valueArray.push((value & 0x7f) | 0x80); - value >>>= 7; - } - valueArray.push(value); - this.serialize(new Uint8Array(valueArray)); - } - - /** - * Returns the buffered bytes - */ - getBytes(): Bytes { - return new Uint8Array(this.buffer).slice(0, this.offset); - } -} - -/** - * Creates a decorator to make sure the arg value of the decorated function is within a range. - * @param minValue The arg value of decorated function must >= minValue - * @param maxValue The arg value of decorated function must <= maxValue - * @param message Error message - */ -function checkNumberRange(minValue: T, maxValue: T, message?: string) { - return (target: unknown, propertyKey: string, descriptor: PropertyDescriptor) => { - const childFunction = descriptor.value; - // eslint-disable-next-line no-param-reassign - descriptor.value = function deco(value: AnyNumber) { - const valueBigInt = BigInt(value.toString()); - if (valueBigInt > BigInt(maxValue.toString()) || valueBigInt < BigInt(minValue.toString())) { - throw new Error(message || "Value is out of range"); - } - childFunction.apply(this, [value]); - }; - return descriptor; - }; -} diff --git a/m1/JavaScript-client/src/bcs/types.ts b/m1/JavaScript-client/src/bcs/types.ts deleted file mode 100644 index f834aa976..000000000 --- a/m1/JavaScript-client/src/bcs/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -export type Seq = T[]; - -export type Uint8 = number; -export type Uint16 = number; -export type Uint32 = number; -export type Uint64 = bigint; -export type Uint128 = bigint; -export type Uint256 = bigint; -export type AnyNumber = bigint | number; -export type Bytes = Uint8Array; diff --git a/m1/JavaScript-client/src/generated/AptosGeneratedClient.ts b/m1/JavaScript-client/src/generated/AptosGeneratedClient.ts deleted file mode 100644 index d7d0952b9..000000000 --- a/m1/JavaScript-client/src/generated/AptosGeneratedClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { BaseHttpRequest } from './core/BaseHttpRequest'; -import type { OpenAPIConfig } from './core/OpenAPI'; -import { AxiosHttpRequest } from './core/AxiosHttpRequest'; - -import { AccountsService } from './services/AccountsService'; -import { BlocksService } from './services/BlocksService'; -import { EventsService } from './services/EventsService'; -import { GeneralService } from './services/GeneralService'; -import { TablesService } from './services/TablesService'; -import { TransactionsService } from './services/TransactionsService'; -import { ViewService } from './services/ViewService'; - -type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest; - -export class AptosGeneratedClient { - - public readonly accounts: AccountsService; - public readonly blocks: BlocksService; - public readonly events: EventsService; - public readonly general: GeneralService; - public readonly tables: TablesService; - public readonly transactions: TransactionsService; - public readonly view: ViewService; - - public readonly request: BaseHttpRequest; - - constructor(config?: Partial, HttpRequest: HttpRequestConstructor = AxiosHttpRequest) { - this.request = new HttpRequest({ - BASE: config?.BASE ?? '/v1', - VERSION: config?.VERSION ?? '1.2.0', - WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false, - CREDENTIALS: config?.CREDENTIALS ?? 'include', - TOKEN: config?.TOKEN, - USERNAME: config?.USERNAME, - PASSWORD: config?.PASSWORD, - HEADERS: config?.HEADERS, - ENCODE_PATH: config?.ENCODE_PATH, - }); - - this.accounts = new AccountsService(this.request); - this.blocks = new BlocksService(this.request); - this.events = new EventsService(this.request); - this.general = new GeneralService(this.request); - this.tables = new TablesService(this.request); - this.transactions = new TransactionsService(this.request); - this.view = new ViewService(this.request); - } -} - diff --git a/m1/JavaScript-client/src/generated/core/ApiError.ts b/m1/JavaScript-client/src/generated/core/ApiError.ts deleted file mode 100644 index 99d792996..000000000 --- a/m1/JavaScript-client/src/generated/core/ApiError.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { ApiRequestOptions } from './ApiRequestOptions'; -import type { ApiResult } from './ApiResult'; - -export class ApiError extends Error { - public readonly url: string; - public readonly status: number; - public readonly statusText: string; - public readonly body: any; - public readonly request: ApiRequestOptions; - - constructor(request: ApiRequestOptions, response: ApiResult, message: string) { - super(message); - - this.name = 'ApiError'; - this.url = response.url; - this.status = response.status; - this.statusText = response.statusText; - this.body = response.body; - this.request = request; - } -} diff --git a/m1/JavaScript-client/src/generated/core/ApiRequestOptions.ts b/m1/JavaScript-client/src/generated/core/ApiRequestOptions.ts deleted file mode 100644 index c7b77538c..000000000 --- a/m1/JavaScript-client/src/generated/core/ApiRequestOptions.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export type ApiRequestOptions = { - readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH'; - readonly url: string; - readonly path?: Record; - readonly cookies?: Record; - readonly headers?: Record; - readonly query?: Record; - readonly formData?: Record; - readonly body?: any; - readonly mediaType?: string; - readonly responseHeader?: string; - readonly errors?: Record; -}; diff --git a/m1/JavaScript-client/src/generated/core/ApiResult.ts b/m1/JavaScript-client/src/generated/core/ApiResult.ts deleted file mode 100644 index b095dc770..000000000 --- a/m1/JavaScript-client/src/generated/core/ApiResult.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export type ApiResult = { - readonly url: string; - readonly ok: boolean; - readonly status: number; - readonly statusText: string; - readonly body: any; -}; diff --git a/m1/JavaScript-client/src/generated/core/AxiosHttpRequest.ts b/m1/JavaScript-client/src/generated/core/AxiosHttpRequest.ts deleted file mode 100644 index 9f6cb3144..000000000 --- a/m1/JavaScript-client/src/generated/core/AxiosHttpRequest.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { ApiRequestOptions } from './ApiRequestOptions'; -import { BaseHttpRequest } from './BaseHttpRequest'; -import type { CancelablePromise } from './CancelablePromise'; -import type { OpenAPIConfig } from './OpenAPI'; -import { request as __request } from './request'; - -export class AxiosHttpRequest extends BaseHttpRequest { - - constructor(config: OpenAPIConfig) { - super(config); - } - - /** - * Request method - * @param options The request options from the service - * @returns CancelablePromise - * @throws ApiError - */ - public request(options: ApiRequestOptions): CancelablePromise { - return __request(this.config, options); - } -} diff --git a/m1/JavaScript-client/src/generated/core/BaseHttpRequest.ts b/m1/JavaScript-client/src/generated/core/BaseHttpRequest.ts deleted file mode 100644 index 1b9700475..000000000 --- a/m1/JavaScript-client/src/generated/core/BaseHttpRequest.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { ApiRequestOptions } from './ApiRequestOptions'; -import type { CancelablePromise } from './CancelablePromise'; -import type { OpenAPIConfig } from './OpenAPI'; - -export abstract class BaseHttpRequest { - - constructor(public readonly config: OpenAPIConfig) {} - - public abstract request(options: ApiRequestOptions): CancelablePromise; -} diff --git a/m1/JavaScript-client/src/generated/core/CancelablePromise.ts b/m1/JavaScript-client/src/generated/core/CancelablePromise.ts deleted file mode 100644 index 26ad30391..000000000 --- a/m1/JavaScript-client/src/generated/core/CancelablePromise.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export class CancelError extends Error { - - constructor(message: string) { - super(message); - this.name = 'CancelError'; - } - - public get isCancelled(): boolean { - return true; - } -} - -export interface OnCancel { - readonly isResolved: boolean; - readonly isRejected: boolean; - readonly isCancelled: boolean; - - (cancelHandler: () => void): void; -} - -export class CancelablePromise implements Promise { - readonly [Symbol.toStringTag]!: string; - - private _isResolved: boolean; - private _isRejected: boolean; - private _isCancelled: boolean; - private readonly _cancelHandlers: (() => void)[]; - private readonly _promise: Promise; - private _resolve?: (value: T | PromiseLike) => void; - private _reject?: (reason?: any) => void; - - constructor( - executor: ( - resolve: (value: T | PromiseLike) => void, - reject: (reason?: any) => void, - onCancel: OnCancel - ) => void - ) { - this._isResolved = false; - this._isRejected = false; - this._isCancelled = false; - this._cancelHandlers = []; - this._promise = new Promise((resolve, reject) => { - this._resolve = resolve; - this._reject = reject; - - const onResolve = (value: T | PromiseLike): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isResolved = true; - this._resolve?.(value); - }; - - const onReject = (reason?: any): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isRejected = true; - this._reject?.(reason); - }; - - const onCancel = (cancelHandler: () => void): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._cancelHandlers.push(cancelHandler); - }; - - Object.defineProperty(onCancel, 'isResolved', { - get: (): boolean => this._isResolved, - }); - - Object.defineProperty(onCancel, 'isRejected', { - get: (): boolean => this._isRejected, - }); - - Object.defineProperty(onCancel, 'isCancelled', { - get: (): boolean => this._isCancelled, - }); - - return executor(onResolve, onReject, onCancel as OnCancel); - }); - } - - public then( - onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: any) => TResult2 | PromiseLike) | null - ): Promise { - return this._promise.then(onFulfilled, onRejected); - } - - public catch( - onRejected?: ((reason: any) => TResult | PromiseLike) | null - ): Promise { - return this._promise.catch(onRejected); - } - - public finally(onFinally?: (() => void) | null): Promise { - return this._promise.finally(onFinally); - } - - public cancel(): void { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isCancelled = true; - if (this._cancelHandlers.length) { - try { - for (const cancelHandler of this._cancelHandlers) { - cancelHandler(); - } - } catch (error) { - console.warn('Cancellation threw an error', error); - return; - } - } - this._cancelHandlers.length = 0; - this._reject?.(new CancelError('Request aborted')); - } - - public get isCancelled(): boolean { - return this._isCancelled; - } -} diff --git a/m1/JavaScript-client/src/generated/core/OpenAPI.ts b/m1/JavaScript-client/src/generated/core/OpenAPI.ts deleted file mode 100644 index 33a73c184..000000000 --- a/m1/JavaScript-client/src/generated/core/OpenAPI.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { ApiRequestOptions } from './ApiRequestOptions'; - -type Resolver = (options: ApiRequestOptions) => Promise; -type Headers = Record; - -export type OpenAPIConfig = { - BASE: string; - VERSION: string; - WITH_CREDENTIALS: boolean; - CREDENTIALS: 'include' | 'omit' | 'same-origin'; - TOKEN?: string | Resolver; - USERNAME?: string | Resolver; - PASSWORD?: string | Resolver; - HEADERS?: Headers | Resolver; - ENCODE_PATH?: (path: string) => string; -}; - -export const OpenAPI: OpenAPIConfig = { - BASE: '/v1', - VERSION: '1.2.0', - WITH_CREDENTIALS: false, - CREDENTIALS: 'include', - TOKEN: undefined, - USERNAME: undefined, - PASSWORD: undefined, - HEADERS: undefined, - ENCODE_PATH: undefined, -}; diff --git a/m1/JavaScript-client/src/generated/core/request.ts b/m1/JavaScript-client/src/generated/core/request.ts deleted file mode 100644 index 286644d1f..000000000 --- a/m1/JavaScript-client/src/generated/core/request.ts +++ /dev/null @@ -1,418 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import axios from 'axios'; -import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'; -import FormData from 'form-data'; - -import { ApiError } from './ApiError'; -import type { ApiRequestOptions } from './ApiRequestOptions'; -import type { ApiResult } from './ApiResult'; -import { CancelablePromise } from './CancelablePromise'; -import type { OnCancel } from './CancelablePromise'; -import type { OpenAPIConfig } from './OpenAPI'; - -interface Cookie { - name: string; - value: string; - expires?: Date; - path?: string; - sameSite?: "Lax" | "None" | "Strict"; - secure?: boolean; -} - -class CookieJar { - constructor(private jar = new Map()) {} - - setCookie(url: URL, cookieStr: string) { - const key = url.origin.toLowerCase(); - if (!this.jar.has(key)) { - this.jar.set(key, []); - } - - const cookie = CookieJar.parse(cookieStr); - this.jar.set(key, [...(this.jar.get(key)?.filter((c) => c.name !== cookie.name) || []), cookie]); - } - - getCookies(url: URL): Cookie[] { - const key = url.origin.toLowerCase(); - if (!this.jar.get(key)) { - return []; - } - - // Filter out expired cookies - return this.jar.get(key)?.filter((cookie) => !cookie.expires || cookie.expires > new Date()) || []; - } - - static parse(str: string): Cookie { - if (typeof str !== "string") { - throw new Error("argument str must be a string"); - } - - const parts = str.split(";").map((part) => part.trim()); - - let cookie: Cookie; - - if (parts.length > 0) { - const [name, value] = parts[0].split("="); - if (!name || !value) { - throw new Error("Invalid cookie"); - } - - cookie = { - name, - value, - }; - } else { - throw new Error("Invalid cookie"); - } - - parts.slice(1).forEach((part) => { - const [name, value] = part.split("="); - if (!name.trim()) { - throw new Error("Invalid cookie"); - } - - const nameLow = name.toLowerCase(); - // eslint-disable-next-line quotes - const val = value?.charAt(0) === "'" || value?.charAt(0) === '"' ? value?.slice(1, -1) : value; - if (nameLow === "expires") { - cookie.expires = new Date(val); - } - if (nameLow === "path") { - cookie.path = val; - } - if (nameLow === "samesite") { - if (val !== "Lax" && val !== "None" && val !== "Strict") { - throw new Error("Invalid cookie SameSite value"); - } - cookie.sameSite = val; - } - if (nameLow === "secure") { - cookie.secure = true; - } - }); - - return cookie; - } -} - -const jar = new CookieJar(); - -axios.interceptors.response.use((response) => { - if (Array.isArray(response.headers["set-cookie"])) { - response.headers["set-cookie"].forEach((c) => { - jar.setCookie(new URL(response.config.url!), c); - }); - } - return response; -}); - -axios.interceptors.request.use(function (config) { - const cookies = jar.getCookies(new URL(config.url!)); - - if (cookies?.length > 0 && config.headers) { - config.headers.cookie = cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; "); - } - return config; -}); - -const isDefined = (value: T | null | undefined): value is Exclude => { - return value !== undefined && value !== null; -}; - -const isString = (value: any): value is string => { - return typeof value === 'string'; -}; - -const isStringWithValue = (value: any): value is string => { - return isString(value) && value !== ''; -}; - -const isBlob = (value: any): value is Blob => { - return ( - typeof value === 'object' && - typeof value.type === 'string' && - typeof value.stream === 'function' && - typeof value.arrayBuffer === 'function' && - typeof value.constructor === 'function' && - typeof value.constructor.name === 'string' && - /^(Blob|File)$/.test(value.constructor.name) && - /^(Blob|File)$/.test(value[Symbol.toStringTag]) - ); -}; - -const isFormData = (value: any): value is FormData => { - return value instanceof FormData; -}; - -const isSuccess = (status: number): boolean => { - return status >= 200 && status < 300; -}; - -const base64 = (str: string): string => { return btoa(str); }; - -const getQueryString = (params: Record): string => { - const qs: string[] = []; - - const append = (key: string, value: any) => { - qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); - }; - - const process = (key: string, value: any) => { - if (isDefined(value)) { - if (Array.isArray(value)) { - value.forEach(v => { - process(key, v); - }); - } else if (typeof value === 'object') { - Object.entries(value).forEach(([k, v]) => { - process(`${key}[${k}]`, v); - }); - } else { - append(key, value); - } - } - }; - - Object.entries(params).forEach(([key, value]) => { - process(key, value); - }); - - if (qs.length > 0) { - return `?${qs.join('&')}`; - } - - return ''; -}; - -const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => { - const encoder = config.ENCODE_PATH || encodeURI; - - const path = options.url - .replace('{api-version}', config.VERSION) - .replace(/{(.*?)}/g, (substring: string, group: string) => { - if (options.path?.hasOwnProperty(group)) { - return encoder(String(options.path[group])); - } - return substring; - }); - - const url = `${config.BASE}${path}`; - if (options.query) { - return `${url}${getQueryString(options.query)}`; - } - return url; -}; - -const getFormData = (options: ApiRequestOptions): FormData | undefined => { - if (options.formData) { - const formData = new FormData(); - - const process = (key: string, value: any) => { - if (isString(value) || isBlob(value)) { - formData.append(key, value); - } else { - formData.append(key, JSON.stringify(value)); - } - }; - - Object.entries(options.formData) - .filter(([_, value]) => isDefined(value)) - .forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach(v => process(key, v)); - } else { - process(key, value); - } - }); - - return formData; - } - return undefined; -}; - -type Resolver = (options: ApiRequestOptions) => Promise; - -const resolve = async (options: ApiRequestOptions, resolver?: T | Resolver): Promise => { - if (typeof resolver === 'function') { - return (resolver as Resolver)(options); - } - return resolver; -}; - -const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise> => { - const token = await resolve(options, config.TOKEN); - const username = await resolve(options, config.USERNAME); - const password = await resolve(options, config.PASSWORD); - const additionalHeaders = await resolve(options, config.HEADERS); - const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {} - - const headers = Object.entries({ - Accept: 'application/json', - ...additionalHeaders, - ...options.headers, - ...formHeaders, - }) - .filter(([_, value]) => isDefined(value)) - .reduce((headers, [key, value]) => ({ - ...headers, - [key]: String(value), - }), {} as Record); - - if (isStringWithValue(token)) { - headers['Authorization'] = `Bearer ${token}`; - } - - if (isStringWithValue(username) && isStringWithValue(password)) { - const credentials = base64(`${username}:${password}`); - headers['Authorization'] = `Basic ${credentials}`; - } - - if (options.body) { - if (options.mediaType) { - headers['Content-Type'] = options.mediaType; - } else if (isBlob(options.body)) { - headers['Content-Type'] = options.body.type || 'application/octet-stream'; - } else if (isString(options.body)) { - headers['Content-Type'] = 'text/plain'; - } else if (!isFormData(options.body)) { - headers['Content-Type'] = 'application/json'; - } - } - - return headers; -}; - -const getRequestBody = (options: ApiRequestOptions): any => { - if (options.body) { - return options.body; - } - return undefined; -}; - -const sendRequest = async ( - config: OpenAPIConfig, - options: ApiRequestOptions, - url: string, - body: any, - formData: FormData | undefined, - headers: Record, - onCancel: OnCancel -): Promise> => { - const source = axios.CancelToken.source(); - - const requestConfig: AxiosRequestConfig = { - url, - headers, - data: body ?? formData, - method: options.method, - withCredentials: config.WITH_CREDENTIALS, - cancelToken: source.token, - }; - - const isBCS = Object.keys(config.HEADERS || {}) - .filter((k) => k.toLowerCase() === "accept") - .map((k) => (config.HEADERS as Record)[k]) - .includes("application/x-bcs"); - if (isBCS) { - requestConfig.responseType = "arraybuffer"; - } - - onCancel(() => source.cancel('The user aborted a request.')); - - try { - return await axios.request(requestConfig); - } catch (error) { - const axiosError = error as AxiosError; - if (axiosError.response) { - return axiosError.response; - } - throw error; - } -}; - -const getResponseHeader = (response: AxiosResponse, responseHeader?: string): string | undefined => { - if (responseHeader) { - const content = response.headers[responseHeader]; - if (isString(content)) { - return content; - } - } - return undefined; -}; - -const getResponseBody = (response: AxiosResponse): any => { - if (response.status !== 204) { - return response.data; - } - return undefined; -}; - -const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { - const errors: Record = { - 400: 'Bad Request', - 401: 'Unauthorized', - 403: 'Forbidden', - 404: 'Not Found', - 429: 'Too Many Requests', - 500: 'Internal Server Error', - 502: 'Bad Gateway', - 503: 'Service Unavailable', - ...options.errors, - } - - const error = errors[result.status]; - if (error) { - throw new ApiError(options, result, error); - } - - if (!result.ok) { - throw new ApiError(options, result, 'Generic Error'); - } -}; - -/** - * Request method - * @param config The OpenAPI configuration object - * @param options The request options from the service - * @returns CancelablePromise - * @throws ApiError - */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { - return new CancelablePromise(async (resolve, reject, onCancel) => { - try { - const url = getUrl(config, options); - const formData = getFormData(options); - const body = getRequestBody(options); - const headers = await getHeaders(config, options, formData); - - if (!onCancel.isCancelled) { - const response = await sendRequest(config, options, url, body, formData, headers, onCancel); - const responseBody = getResponseBody(response); - const responseHeader = getResponseHeader(response, options.responseHeader); - - const result: ApiResult = { - url, - ok: isSuccess(response.status), - status: response.status, - statusText: response.statusText, - body: responseHeader ?? responseBody, - }; - - catchErrorCodes(options, result); - - // Attach the response headers to the output. This is a hack to fix - // https://github.com/ferdikoomen/openapi-typescript-codegen/issues/1295 - const out = result.body; - try { - out["__headers"] = response.headers; - } catch (_) {} - - resolve(out); - } - } catch (error) { - reject(error); - } - }); -}; diff --git a/m1/JavaScript-client/src/generated/index.ts b/m1/JavaScript-client/src/generated/index.ts deleted file mode 100644 index e925af3a8..000000000 --- a/m1/JavaScript-client/src/generated/index.ts +++ /dev/null @@ -1,214 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export { AptosGeneratedClient } from './AptosGeneratedClient'; - -export { ApiError } from './core/ApiError'; -export { BaseHttpRequest } from './core/BaseHttpRequest'; -export { CancelablePromise, CancelError } from './core/CancelablePromise'; -export { OpenAPI } from './core/OpenAPI'; -export type { OpenAPIConfig } from './core/OpenAPI'; - -export type { AccountData } from './models/AccountData'; -export type { AccountSignature } from './models/AccountSignature'; -export type { AccountSignature_Ed25519Signature } from './models/AccountSignature_Ed25519Signature'; -export type { AccountSignature_MultiEd25519Signature } from './models/AccountSignature_MultiEd25519Signature'; -export type { Address } from './models/Address'; -export type { AptosError } from './models/AptosError'; -export { AptosErrorCode } from './models/AptosErrorCode'; -export type { Block } from './models/Block'; -export type { BlockMetadataTransaction } from './models/BlockMetadataTransaction'; -export type { DecodedTableData } from './models/DecodedTableData'; -export type { DeletedTableData } from './models/DeletedTableData'; -export type { DeleteModule } from './models/DeleteModule'; -export type { DeleteResource } from './models/DeleteResource'; -export type { DeleteTableItem } from './models/DeleteTableItem'; -export type { DirectWriteSet } from './models/DirectWriteSet'; -export type { Ed25519Signature } from './models/Ed25519Signature'; -export type { EncodeSubmissionRequest } from './models/EncodeSubmissionRequest'; -export type { EntryFunctionId } from './models/EntryFunctionId'; -export type { EntryFunctionPayload } from './models/EntryFunctionPayload'; -export type { Event } from './models/Event'; -export type { EventGuid } from './models/EventGuid'; -export type { GasEstimation } from './models/GasEstimation'; -export type { GenesisPayload } from './models/GenesisPayload'; -export type { GenesisPayload_WriteSetPayload } from './models/GenesisPayload_WriteSetPayload'; -export type { GenesisTransaction } from './models/GenesisTransaction'; -export type { HashValue } from './models/HashValue'; -export type { HealthCheckSuccess } from './models/HealthCheckSuccess'; -export type { HexEncodedBytes } from './models/HexEncodedBytes'; -export type { IdentifierWrapper } from './models/IdentifierWrapper'; -export type { IndexResponse } from './models/IndexResponse'; -export type { ModuleBundlePayload } from './models/ModuleBundlePayload'; -export type { MoveAbility } from './models/MoveAbility'; -export type { MoveFunction } from './models/MoveFunction'; -export type { MoveFunctionGenericTypeParam } from './models/MoveFunctionGenericTypeParam'; -export { MoveFunctionVisibility } from './models/MoveFunctionVisibility'; -export type { MoveModule } from './models/MoveModule'; -export type { MoveModuleBytecode } from './models/MoveModuleBytecode'; -export type { MoveModuleId } from './models/MoveModuleId'; -export type { MoveResource } from './models/MoveResource'; -export type { MoveScriptBytecode } from './models/MoveScriptBytecode'; -export type { MoveStruct } from './models/MoveStruct'; -export type { MoveStructField } from './models/MoveStructField'; -export type { MoveStructGenericTypeParam } from './models/MoveStructGenericTypeParam'; -export type { MoveStructTag } from './models/MoveStructTag'; -export type { MoveStructValue } from './models/MoveStructValue'; -export type { MoveType } from './models/MoveType'; -export type { MoveValue } from './models/MoveValue'; -export type { MultiAgentSignature } from './models/MultiAgentSignature'; -export type { MultiEd25519Signature } from './models/MultiEd25519Signature'; -export type { MultisigPayload } from './models/MultisigPayload'; -export type { MultisigTransactionPayload } from './models/MultisigTransactionPayload'; -export type { PendingTransaction } from './models/PendingTransaction'; -export type { RawTableItemRequest } from './models/RawTableItemRequest'; -export { RoleType } from './models/RoleType'; -export type { ScriptPayload } from './models/ScriptPayload'; -export type { ScriptWriteSet } from './models/ScriptWriteSet'; -export type { StateCheckpointTransaction } from './models/StateCheckpointTransaction'; -export type { StateKeyWrapper } from './models/StateKeyWrapper'; -export type { SubmitTransactionRequest } from './models/SubmitTransactionRequest'; -export type { TableItemRequest } from './models/TableItemRequest'; -export type { Transaction } from './models/Transaction'; -export type { Transaction_BlockMetadataTransaction } from './models/Transaction_BlockMetadataTransaction'; -export type { Transaction_GenesisTransaction } from './models/Transaction_GenesisTransaction'; -export type { Transaction_PendingTransaction } from './models/Transaction_PendingTransaction'; -export type { Transaction_StateCheckpointTransaction } from './models/Transaction_StateCheckpointTransaction'; -export type { Transaction_UserTransaction } from './models/Transaction_UserTransaction'; -export type { TransactionPayload } from './models/TransactionPayload'; -export type { TransactionPayload_EntryFunctionPayload } from './models/TransactionPayload_EntryFunctionPayload'; -export type { TransactionPayload_ModuleBundlePayload } from './models/TransactionPayload_ModuleBundlePayload'; -export type { TransactionPayload_MultisigPayload } from './models/TransactionPayload_MultisigPayload'; -export type { TransactionPayload_ScriptPayload } from './models/TransactionPayload_ScriptPayload'; -export type { TransactionsBatchSingleSubmissionFailure } from './models/TransactionsBatchSingleSubmissionFailure'; -export type { TransactionsBatchSubmissionResult } from './models/TransactionsBatchSubmissionResult'; -export type { TransactionSignature } from './models/TransactionSignature'; -export type { TransactionSignature_Ed25519Signature } from './models/TransactionSignature_Ed25519Signature'; -export type { TransactionSignature_MultiAgentSignature } from './models/TransactionSignature_MultiAgentSignature'; -export type { TransactionSignature_MultiEd25519Signature } from './models/TransactionSignature_MultiEd25519Signature'; -export type { U128 } from './models/U128'; -export type { U256 } from './models/U256'; -export type { U64 } from './models/U64'; -export type { UserTransaction } from './models/UserTransaction'; -export type { VersionedEvent } from './models/VersionedEvent'; -export type { ViewRequest } from './models/ViewRequest'; -export type { WriteModule } from './models/WriteModule'; -export type { WriteResource } from './models/WriteResource'; -export type { WriteSet } from './models/WriteSet'; -export type { WriteSet_DirectWriteSet } from './models/WriteSet_DirectWriteSet'; -export type { WriteSet_ScriptWriteSet } from './models/WriteSet_ScriptWriteSet'; -export type { WriteSetChange } from './models/WriteSetChange'; -export type { WriteSetChange_DeleteModule } from './models/WriteSetChange_DeleteModule'; -export type { WriteSetChange_DeleteResource } from './models/WriteSetChange_DeleteResource'; -export type { WriteSetChange_DeleteTableItem } from './models/WriteSetChange_DeleteTableItem'; -export type { WriteSetChange_WriteModule } from './models/WriteSetChange_WriteModule'; -export type { WriteSetChange_WriteResource } from './models/WriteSetChange_WriteResource'; -export type { WriteSetChange_WriteTableItem } from './models/WriteSetChange_WriteTableItem'; -export type { WriteSetPayload } from './models/WriteSetPayload'; -export type { WriteTableItem } from './models/WriteTableItem'; - -export { $AccountData } from './schemas/$AccountData'; -export { $AccountSignature } from './schemas/$AccountSignature'; -export { $AccountSignature_Ed25519Signature } from './schemas/$AccountSignature_Ed25519Signature'; -export { $AccountSignature_MultiEd25519Signature } from './schemas/$AccountSignature_MultiEd25519Signature'; -export { $Address } from './schemas/$Address'; -export { $AptosError } from './schemas/$AptosError'; -export { $AptosErrorCode } from './schemas/$AptosErrorCode'; -export { $Block } from './schemas/$Block'; -export { $BlockMetadataTransaction } from './schemas/$BlockMetadataTransaction'; -export { $DecodedTableData } from './schemas/$DecodedTableData'; -export { $DeletedTableData } from './schemas/$DeletedTableData'; -export { $DeleteModule } from './schemas/$DeleteModule'; -export { $DeleteResource } from './schemas/$DeleteResource'; -export { $DeleteTableItem } from './schemas/$DeleteTableItem'; -export { $DirectWriteSet } from './schemas/$DirectWriteSet'; -export { $Ed25519Signature } from './schemas/$Ed25519Signature'; -export { $EncodeSubmissionRequest } from './schemas/$EncodeSubmissionRequest'; -export { $EntryFunctionId } from './schemas/$EntryFunctionId'; -export { $EntryFunctionPayload } from './schemas/$EntryFunctionPayload'; -export { $Event } from './schemas/$Event'; -export { $EventGuid } from './schemas/$EventGuid'; -export { $GasEstimation } from './schemas/$GasEstimation'; -export { $GenesisPayload } from './schemas/$GenesisPayload'; -export { $GenesisPayload_WriteSetPayload } from './schemas/$GenesisPayload_WriteSetPayload'; -export { $GenesisTransaction } from './schemas/$GenesisTransaction'; -export { $HashValue } from './schemas/$HashValue'; -export { $HealthCheckSuccess } from './schemas/$HealthCheckSuccess'; -export { $HexEncodedBytes } from './schemas/$HexEncodedBytes'; -export { $IdentifierWrapper } from './schemas/$IdentifierWrapper'; -export { $IndexResponse } from './schemas/$IndexResponse'; -export { $ModuleBundlePayload } from './schemas/$ModuleBundlePayload'; -export { $MoveAbility } from './schemas/$MoveAbility'; -export { $MoveFunction } from './schemas/$MoveFunction'; -export { $MoveFunctionGenericTypeParam } from './schemas/$MoveFunctionGenericTypeParam'; -export { $MoveFunctionVisibility } from './schemas/$MoveFunctionVisibility'; -export { $MoveModule } from './schemas/$MoveModule'; -export { $MoveModuleBytecode } from './schemas/$MoveModuleBytecode'; -export { $MoveModuleId } from './schemas/$MoveModuleId'; -export { $MoveResource } from './schemas/$MoveResource'; -export { $MoveScriptBytecode } from './schemas/$MoveScriptBytecode'; -export { $MoveStruct } from './schemas/$MoveStruct'; -export { $MoveStructField } from './schemas/$MoveStructField'; -export { $MoveStructGenericTypeParam } from './schemas/$MoveStructGenericTypeParam'; -export { $MoveStructTag } from './schemas/$MoveStructTag'; -export { $MoveStructValue } from './schemas/$MoveStructValue'; -export { $MoveType } from './schemas/$MoveType'; -export { $MoveValue } from './schemas/$MoveValue'; -export { $MultiAgentSignature } from './schemas/$MultiAgentSignature'; -export { $MultiEd25519Signature } from './schemas/$MultiEd25519Signature'; -export { $MultisigPayload } from './schemas/$MultisigPayload'; -export { $MultisigTransactionPayload } from './schemas/$MultisigTransactionPayload'; -export { $PendingTransaction } from './schemas/$PendingTransaction'; -export { $RawTableItemRequest } from './schemas/$RawTableItemRequest'; -export { $RoleType } from './schemas/$RoleType'; -export { $ScriptPayload } from './schemas/$ScriptPayload'; -export { $ScriptWriteSet } from './schemas/$ScriptWriteSet'; -export { $StateCheckpointTransaction } from './schemas/$StateCheckpointTransaction'; -export { $StateKeyWrapper } from './schemas/$StateKeyWrapper'; -export { $SubmitTransactionRequest } from './schemas/$SubmitTransactionRequest'; -export { $TableItemRequest } from './schemas/$TableItemRequest'; -export { $Transaction } from './schemas/$Transaction'; -export { $Transaction_BlockMetadataTransaction } from './schemas/$Transaction_BlockMetadataTransaction'; -export { $Transaction_GenesisTransaction } from './schemas/$Transaction_GenesisTransaction'; -export { $Transaction_PendingTransaction } from './schemas/$Transaction_PendingTransaction'; -export { $Transaction_StateCheckpointTransaction } from './schemas/$Transaction_StateCheckpointTransaction'; -export { $Transaction_UserTransaction } from './schemas/$Transaction_UserTransaction'; -export { $TransactionPayload } from './schemas/$TransactionPayload'; -export { $TransactionPayload_EntryFunctionPayload } from './schemas/$TransactionPayload_EntryFunctionPayload'; -export { $TransactionPayload_ModuleBundlePayload } from './schemas/$TransactionPayload_ModuleBundlePayload'; -export { $TransactionPayload_MultisigPayload } from './schemas/$TransactionPayload_MultisigPayload'; -export { $TransactionPayload_ScriptPayload } from './schemas/$TransactionPayload_ScriptPayload'; -export { $TransactionsBatchSingleSubmissionFailure } from './schemas/$TransactionsBatchSingleSubmissionFailure'; -export { $TransactionsBatchSubmissionResult } from './schemas/$TransactionsBatchSubmissionResult'; -export { $TransactionSignature } from './schemas/$TransactionSignature'; -export { $TransactionSignature_Ed25519Signature } from './schemas/$TransactionSignature_Ed25519Signature'; -export { $TransactionSignature_MultiAgentSignature } from './schemas/$TransactionSignature_MultiAgentSignature'; -export { $TransactionSignature_MultiEd25519Signature } from './schemas/$TransactionSignature_MultiEd25519Signature'; -export { $U128 } from './schemas/$U128'; -export { $U256 } from './schemas/$U256'; -export { $U64 } from './schemas/$U64'; -export { $UserTransaction } from './schemas/$UserTransaction'; -export { $VersionedEvent } from './schemas/$VersionedEvent'; -export { $ViewRequest } from './schemas/$ViewRequest'; -export { $WriteModule } from './schemas/$WriteModule'; -export { $WriteResource } from './schemas/$WriteResource'; -export { $WriteSet } from './schemas/$WriteSet'; -export { $WriteSet_DirectWriteSet } from './schemas/$WriteSet_DirectWriteSet'; -export { $WriteSet_ScriptWriteSet } from './schemas/$WriteSet_ScriptWriteSet'; -export { $WriteSetChange } from './schemas/$WriteSetChange'; -export { $WriteSetChange_DeleteModule } from './schemas/$WriteSetChange_DeleteModule'; -export { $WriteSetChange_DeleteResource } from './schemas/$WriteSetChange_DeleteResource'; -export { $WriteSetChange_DeleteTableItem } from './schemas/$WriteSetChange_DeleteTableItem'; -export { $WriteSetChange_WriteModule } from './schemas/$WriteSetChange_WriteModule'; -export { $WriteSetChange_WriteResource } from './schemas/$WriteSetChange_WriteResource'; -export { $WriteSetChange_WriteTableItem } from './schemas/$WriteSetChange_WriteTableItem'; -export { $WriteSetPayload } from './schemas/$WriteSetPayload'; -export { $WriteTableItem } from './schemas/$WriteTableItem'; - -export { AccountsService } from './services/AccountsService'; -export { BlocksService } from './services/BlocksService'; -export { EventsService } from './services/EventsService'; -export { GeneralService } from './services/GeneralService'; -export { TablesService } from './services/TablesService'; -export { TransactionsService } from './services/TransactionsService'; -export { ViewService } from './services/ViewService'; diff --git a/m1/JavaScript-client/src/generated/models/AccountData.ts b/m1/JavaScript-client/src/generated/models/AccountData.ts deleted file mode 100644 index 8df40aa85..000000000 --- a/m1/JavaScript-client/src/generated/models/AccountData.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HexEncodedBytes } from './HexEncodedBytes'; -import type { U64 } from './U64'; - -/** - * Account data - * - * A simplified version of the onchain Account resource - */ -export type AccountData = { - sequence_number: U64; - authentication_key: HexEncodedBytes; -}; - diff --git a/m1/JavaScript-client/src/generated/models/AccountSignature.ts b/m1/JavaScript-client/src/generated/models/AccountSignature.ts deleted file mode 100644 index 576d1507d..000000000 --- a/m1/JavaScript-client/src/generated/models/AccountSignature.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { AccountSignature_Ed25519Signature } from './AccountSignature_Ed25519Signature'; -import type { AccountSignature_MultiEd25519Signature } from './AccountSignature_MultiEd25519Signature'; - -/** - * Account signature scheme - * - * The account signature scheme allows you to have two types of accounts: - * - * 1. A single Ed25519 key account, one private key - * 2. A k-of-n multi-Ed25519 key account, multiple private keys, such that k-of-n must sign a transaction. - */ -export type AccountSignature = (AccountSignature_Ed25519Signature | AccountSignature_MultiEd25519Signature); - diff --git a/m1/JavaScript-client/src/generated/models/AccountSignature_Ed25519Signature.ts b/m1/JavaScript-client/src/generated/models/AccountSignature_Ed25519Signature.ts deleted file mode 100644 index 3d91da519..000000000 --- a/m1/JavaScript-client/src/generated/models/AccountSignature_Ed25519Signature.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Ed25519Signature } from './Ed25519Signature'; - -export type AccountSignature_Ed25519Signature = ({ - type: string; -} & Ed25519Signature); - diff --git a/m1/JavaScript-client/src/generated/models/AccountSignature_MultiEd25519Signature.ts b/m1/JavaScript-client/src/generated/models/AccountSignature_MultiEd25519Signature.ts deleted file mode 100644 index 11acab2eb..000000000 --- a/m1/JavaScript-client/src/generated/models/AccountSignature_MultiEd25519Signature.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MultiEd25519Signature } from './MultiEd25519Signature'; - -export type AccountSignature_MultiEd25519Signature = ({ - type: string; -} & MultiEd25519Signature); - diff --git a/m1/JavaScript-client/src/generated/models/Address.ts b/m1/JavaScript-client/src/generated/models/Address.ts deleted file mode 100644 index 03c32f6b4..000000000 --- a/m1/JavaScript-client/src/generated/models/Address.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * A hex encoded 32 byte Aptos account address. - * - * This is represented in a string as a 64 character hex string, sometimes - * shortened by stripping leading 0s, and adding a 0x. - * - * For example, address 0x0000000000000000000000000000000000000000000000000000000000000001 is represented as 0x1. - * - */ -export type Address = string; diff --git a/m1/JavaScript-client/src/generated/models/AptosError.ts b/m1/JavaScript-client/src/generated/models/AptosError.ts deleted file mode 100644 index ed24d5524..000000000 --- a/m1/JavaScript-client/src/generated/models/AptosError.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { AptosErrorCode } from './AptosErrorCode'; - -/** - * This is the generic struct we use for all API errors, it contains a string - * message and an Aptos API specific error code. - */ -export type AptosError = { - /** - * A message describing the error - */ - message: string; - error_code: AptosErrorCode; - /** - * A code providing VM error details when submitting transactions to the VM - */ - vm_error_code?: number; -}; - diff --git a/m1/JavaScript-client/src/generated/models/AptosErrorCode.ts b/m1/JavaScript-client/src/generated/models/AptosErrorCode.ts deleted file mode 100644 index 317b13b1b..000000000 --- a/m1/JavaScript-client/src/generated/models/AptosErrorCode.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * These codes provide more granular error information beyond just the HTTP - * status code of the response. - */ -export enum AptosErrorCode { - ACCOUNT_NOT_FOUND = 'account_not_found', - RESOURCE_NOT_FOUND = 'resource_not_found', - MODULE_NOT_FOUND = 'module_not_found', - STRUCT_FIELD_NOT_FOUND = 'struct_field_not_found', - VERSION_NOT_FOUND = 'version_not_found', - TRANSACTION_NOT_FOUND = 'transaction_not_found', - TABLE_ITEM_NOT_FOUND = 'table_item_not_found', - BLOCK_NOT_FOUND = 'block_not_found', - VERSION_PRUNED = 'version_pruned', - BLOCK_PRUNED = 'block_pruned', - INVALID_INPUT = 'invalid_input', - INVALID_TRANSACTION_UPDATE = 'invalid_transaction_update', - SEQUENCE_NUMBER_TOO_OLD = 'sequence_number_too_old', - VM_ERROR = 'vm_error', - HEALTH_CHECK_FAILED = 'health_check_failed', - MEMPOOL_IS_FULL = 'mempool_is_full', - INTERNAL_ERROR = 'internal_error', - WEB_FRAMEWORK_ERROR = 'web_framework_error', - BCS_NOT_SUPPORTED = 'bcs_not_supported', - API_DISABLED = 'api_disabled', -} diff --git a/m1/JavaScript-client/src/generated/models/Block.ts b/m1/JavaScript-client/src/generated/models/Block.ts deleted file mode 100644 index e6c2a57e3..000000000 --- a/m1/JavaScript-client/src/generated/models/Block.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HashValue } from './HashValue'; -import type { Transaction } from './Transaction'; -import type { U64 } from './U64'; - -/** - * A Block with or without transactions - * - * This contains the information about a transactions along with - * associated transactions if requested - */ -export type Block = { - block_height: U64; - block_hash: HashValue; - block_timestamp: U64; - first_version: U64; - last_version: U64; - /** - * The transactions in the block in sequential order - */ - transactions?: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/BlockMetadataTransaction.ts b/m1/JavaScript-client/src/generated/models/BlockMetadataTransaction.ts deleted file mode 100644 index 9ec5828de..000000000 --- a/m1/JavaScript-client/src/generated/models/BlockMetadataTransaction.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { Event } from './Event'; -import type { HashValue } from './HashValue'; -import type { U64 } from './U64'; -import type { WriteSetChange } from './WriteSetChange'; - -/** - * A block metadata transaction - * - * This signifies the beginning of a block, and contains information - * about the specific block - */ -export type BlockMetadataTransaction = { - version: U64; - hash: HashValue; - state_change_hash: HashValue; - event_root_hash: HashValue; - state_checkpoint_hash?: HashValue; - gas_used: U64; - /** - * Whether the transaction was successful - */ - success: boolean; - /** - * The VM status of the transaction, can tell useful information in a failure - */ - vm_status: string; - accumulator_root_hash: HashValue; - /** - * Final state of resources changed by the transaction - */ - changes: Array; - id: HashValue; - epoch: U64; - round: U64; - /** - * The events emitted at the block creation - */ - events: Array; - /** - * Previous block votes - */ - previous_block_votes_bitvec: Array; - proposer: Address; - /** - * The indices of the proposers who failed to propose - */ - failed_proposer_indices: Array; - timestamp: U64; -}; - diff --git a/m1/JavaScript-client/src/generated/models/DecodedTableData.ts b/m1/JavaScript-client/src/generated/models/DecodedTableData.ts deleted file mode 100644 index 83571f4fe..000000000 --- a/m1/JavaScript-client/src/generated/models/DecodedTableData.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Decoded table data - */ -export type DecodedTableData = { - /** - * Key of table in JSON - */ - key: any; - /** - * Type of key - */ - key_type: string; - /** - * Value of table in JSON - */ - value: any; - /** - * Type of value - */ - value_type: string; -}; - diff --git a/m1/JavaScript-client/src/generated/models/DeleteModule.ts b/m1/JavaScript-client/src/generated/models/DeleteModule.ts deleted file mode 100644 index 44d49ce0c..000000000 --- a/m1/JavaScript-client/src/generated/models/DeleteModule.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { MoveModuleId } from './MoveModuleId'; - -/** - * Delete a module - */ -export type DeleteModule = { - address: Address; - /** - * State key hash - */ - state_key_hash: string; - module: MoveModuleId; -}; - diff --git a/m1/JavaScript-client/src/generated/models/DeleteResource.ts b/m1/JavaScript-client/src/generated/models/DeleteResource.ts deleted file mode 100644 index ff863a949..000000000 --- a/m1/JavaScript-client/src/generated/models/DeleteResource.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { MoveStructTag } from './MoveStructTag'; - -/** - * Delete a resource - */ -export type DeleteResource = { - address: Address; - /** - * State key hash - */ - state_key_hash: string; - resource: MoveStructTag; -}; - diff --git a/m1/JavaScript-client/src/generated/models/DeleteTableItem.ts b/m1/JavaScript-client/src/generated/models/DeleteTableItem.ts deleted file mode 100644 index c2655d4f5..000000000 --- a/m1/JavaScript-client/src/generated/models/DeleteTableItem.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DeletedTableData } from './DeletedTableData'; -import type { HexEncodedBytes } from './HexEncodedBytes'; - -/** - * Delete a table item - */ -export type DeleteTableItem = { - state_key_hash: string; - handle: HexEncodedBytes; - key: HexEncodedBytes; - data?: DeletedTableData; -}; - diff --git a/m1/JavaScript-client/src/generated/models/DeletedTableData.ts b/m1/JavaScript-client/src/generated/models/DeletedTableData.ts deleted file mode 100644 index ccf4fd6e9..000000000 --- a/m1/JavaScript-client/src/generated/models/DeletedTableData.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Deleted table data - */ -export type DeletedTableData = { - /** - * Deleted key - */ - key: any; - /** - * Deleted key type - */ - key_type: string; -}; - diff --git a/m1/JavaScript-client/src/generated/models/DirectWriteSet.ts b/m1/JavaScript-client/src/generated/models/DirectWriteSet.ts deleted file mode 100644 index 1c09731f0..000000000 --- a/m1/JavaScript-client/src/generated/models/DirectWriteSet.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Event } from './Event'; -import type { WriteSetChange } from './WriteSetChange'; - -export type DirectWriteSet = { - changes: Array; - events: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/Ed25519Signature.ts b/m1/JavaScript-client/src/generated/models/Ed25519Signature.ts deleted file mode 100644 index 27686cec8..000000000 --- a/m1/JavaScript-client/src/generated/models/Ed25519Signature.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HexEncodedBytes } from './HexEncodedBytes'; - -/** - * A single Ed25519 signature - */ -export type Ed25519Signature = { - public_key: HexEncodedBytes; - signature: HexEncodedBytes; -}; - diff --git a/m1/JavaScript-client/src/generated/models/EncodeSubmissionRequest.ts b/m1/JavaScript-client/src/generated/models/EncodeSubmissionRequest.ts deleted file mode 100644 index 52e6f903e..000000000 --- a/m1/JavaScript-client/src/generated/models/EncodeSubmissionRequest.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { TransactionPayload } from './TransactionPayload'; -import type { U64 } from './U64'; - -/** - * Request to encode a submission - */ -export type EncodeSubmissionRequest = { - sender: Address; - sequence_number: U64; - max_gas_amount: U64; - gas_unit_price: U64; - expiration_timestamp_secs: U64; - payload: TransactionPayload; - /** - * Secondary signer accounts of the request for Multi-agent - */ - secondary_signers?: Array
; -}; - diff --git a/m1/JavaScript-client/src/generated/models/EntryFunctionId.ts b/m1/JavaScript-client/src/generated/models/EntryFunctionId.ts deleted file mode 100644 index f38310d0c..000000000 --- a/m1/JavaScript-client/src/generated/models/EntryFunctionId.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Entry function id is string representation of a entry function defined on-chain. - * - * Format: `{address}::{module name}::{function name}` - * - * Both `module name` and `function name` are case-sensitive. - * - */ -export type EntryFunctionId = string; diff --git a/m1/JavaScript-client/src/generated/models/EntryFunctionPayload.ts b/m1/JavaScript-client/src/generated/models/EntryFunctionPayload.ts deleted file mode 100644 index 78a3ee67d..000000000 --- a/m1/JavaScript-client/src/generated/models/EntryFunctionPayload.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EntryFunctionId } from './EntryFunctionId'; -import type { MoveType } from './MoveType'; - -/** - * Payload which runs a single entry function - */ -export type EntryFunctionPayload = { - function: EntryFunctionId; - /** - * Type arguments of the function - */ - type_arguments: Array; - /** - * Arguments of the function - */ - arguments: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/Event.ts b/m1/JavaScript-client/src/generated/models/Event.ts deleted file mode 100644 index a160a00cc..000000000 --- a/m1/JavaScript-client/src/generated/models/Event.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EventGuid } from './EventGuid'; -import type { MoveType } from './MoveType'; -import type { U64 } from './U64'; - -/** - * An event from a transaction - */ -export type Event = { - guid: EventGuid; - sequence_number: U64; - type: MoveType; - /** - * The JSON representation of the event - */ - data: any; -}; - diff --git a/m1/JavaScript-client/src/generated/models/EventGuid.ts b/m1/JavaScript-client/src/generated/models/EventGuid.ts deleted file mode 100644 index 928ad847f..000000000 --- a/m1/JavaScript-client/src/generated/models/EventGuid.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { U64 } from './U64'; - -export type EventGuid = { - creation_number: U64; - account_address: Address; -}; - diff --git a/m1/JavaScript-client/src/generated/models/GasEstimation.ts b/m1/JavaScript-client/src/generated/models/GasEstimation.ts deleted file mode 100644 index f8ebd6993..000000000 --- a/m1/JavaScript-client/src/generated/models/GasEstimation.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Struct holding the outputs of the estimate gas API - */ -export type GasEstimation = { - /** - * The deprioritized estimate for the gas unit price - */ - deprioritized_gas_estimate?: number; - /** - * The current estimate for the gas unit price - */ - gas_estimate: number; - /** - * The prioritized estimate for the gas unit price - */ - prioritized_gas_estimate?: number; -}; - diff --git a/m1/JavaScript-client/src/generated/models/GenesisPayload.ts b/m1/JavaScript-client/src/generated/models/GenesisPayload.ts deleted file mode 100644 index 66d653a68..000000000 --- a/m1/JavaScript-client/src/generated/models/GenesisPayload.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { GenesisPayload_WriteSetPayload } from './GenesisPayload_WriteSetPayload'; - -/** - * The writeset payload of the Genesis transaction - */ -export type GenesisPayload = GenesisPayload_WriteSetPayload; - diff --git a/m1/JavaScript-client/src/generated/models/GenesisPayload_WriteSetPayload.ts b/m1/JavaScript-client/src/generated/models/GenesisPayload_WriteSetPayload.ts deleted file mode 100644 index a61275063..000000000 --- a/m1/JavaScript-client/src/generated/models/GenesisPayload_WriteSetPayload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { WriteSetPayload } from './WriteSetPayload'; - -export type GenesisPayload_WriteSetPayload = ({ - type: string; -} & WriteSetPayload); - diff --git a/m1/JavaScript-client/src/generated/models/GenesisTransaction.ts b/m1/JavaScript-client/src/generated/models/GenesisTransaction.ts deleted file mode 100644 index 563a8be8f..000000000 --- a/m1/JavaScript-client/src/generated/models/GenesisTransaction.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Event } from './Event'; -import type { GenesisPayload } from './GenesisPayload'; -import type { HashValue } from './HashValue'; -import type { U64 } from './U64'; -import type { WriteSetChange } from './WriteSetChange'; - -/** - * The genesis transaction - * - * This only occurs at the genesis transaction (version 0) - */ -export type GenesisTransaction = { - version: U64; - hash: HashValue; - state_change_hash: HashValue; - event_root_hash: HashValue; - state_checkpoint_hash?: HashValue; - gas_used: U64; - /** - * Whether the transaction was successful - */ - success: boolean; - /** - * The VM status of the transaction, can tell useful information in a failure - */ - vm_status: string; - accumulator_root_hash: HashValue; - /** - * Final state of resources changed by the transaction - */ - changes: Array; - payload: GenesisPayload; - /** - * Events emitted during genesis - */ - events: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/HashValue.ts b/m1/JavaScript-client/src/generated/models/HashValue.ts deleted file mode 100644 index a296dd84c..000000000 --- a/m1/JavaScript-client/src/generated/models/HashValue.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -export type HashValue = string; diff --git a/m1/JavaScript-client/src/generated/models/HealthCheckSuccess.ts b/m1/JavaScript-client/src/generated/models/HealthCheckSuccess.ts deleted file mode 100644 index ff98f0ed7..000000000 --- a/m1/JavaScript-client/src/generated/models/HealthCheckSuccess.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Representation of a successful healthcheck - */ -export type HealthCheckSuccess = { - message: string; -}; - diff --git a/m1/JavaScript-client/src/generated/models/HexEncodedBytes.ts b/m1/JavaScript-client/src/generated/models/HexEncodedBytes.ts deleted file mode 100644 index d4a21baf0..000000000 --- a/m1/JavaScript-client/src/generated/models/HexEncodedBytes.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * All bytes (Vec) data is represented as hex-encoded string prefixed with `0x` and fulfilled with - * two hex digits per byte. - * - * Unlike the `Address` type, HexEncodedBytes will not trim any zeros. - * - */ -export type HexEncodedBytes = string; diff --git a/m1/JavaScript-client/src/generated/models/IdentifierWrapper.ts b/m1/JavaScript-client/src/generated/models/IdentifierWrapper.ts deleted file mode 100644 index 8bf5d9a71..000000000 --- a/m1/JavaScript-client/src/generated/models/IdentifierWrapper.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -export type IdentifierWrapper = string; diff --git a/m1/JavaScript-client/src/generated/models/IndexResponse.ts b/m1/JavaScript-client/src/generated/models/IndexResponse.ts deleted file mode 100644 index 1ca2519b1..000000000 --- a/m1/JavaScript-client/src/generated/models/IndexResponse.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { RoleType } from './RoleType'; -import type { U64 } from './U64'; - -/** - * The struct holding all data returned to the client by the - * index endpoint (i.e., GET "/"). Only for responding in JSON - */ -export type IndexResponse = { - /** - * Chain ID of the current chain - */ - chain_id: number; - epoch: U64; - ledger_version: U64; - oldest_ledger_version: U64; - ledger_timestamp: U64; - node_role: RoleType; - oldest_block_height: U64; - block_height: U64; - /** - * Git hash of the build of the API endpoint. Can be used to determine the exact - * software version used by the API endpoint. - */ - git_hash?: string; -}; - diff --git a/m1/JavaScript-client/src/generated/models/ModuleBundlePayload.ts b/m1/JavaScript-client/src/generated/models/ModuleBundlePayload.ts deleted file mode 100644 index be34a1f42..000000000 --- a/m1/JavaScript-client/src/generated/models/ModuleBundlePayload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MoveModuleBytecode } from './MoveModuleBytecode'; - -export type ModuleBundlePayload = { - modules: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveAbility.ts b/m1/JavaScript-client/src/generated/models/MoveAbility.ts deleted file mode 100644 index 311c5db90..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveAbility.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -export type MoveAbility = string; diff --git a/m1/JavaScript-client/src/generated/models/MoveFunction.ts b/m1/JavaScript-client/src/generated/models/MoveFunction.ts deleted file mode 100644 index 4ce3ad729..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveFunction.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { IdentifierWrapper } from './IdentifierWrapper'; -import type { MoveFunctionGenericTypeParam } from './MoveFunctionGenericTypeParam'; -import type { MoveFunctionVisibility } from './MoveFunctionVisibility'; -import type { MoveType } from './MoveType'; - -/** - * Move function - */ -export type MoveFunction = { - name: IdentifierWrapper; - visibility: MoveFunctionVisibility; - /** - * Whether the function can be called as an entry function directly in a transaction - */ - is_entry: boolean; - /** - * Whether the function is a view function or not - */ - is_view: boolean; - /** - * Generic type params associated with the Move function - */ - generic_type_params: Array; - /** - * Parameters associated with the move function - */ - params: Array; - /** - * Return type of the function - */ - return: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveFunctionGenericTypeParam.ts b/m1/JavaScript-client/src/generated/models/MoveFunctionGenericTypeParam.ts deleted file mode 100644 index c0776fe5c..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveFunctionGenericTypeParam.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MoveAbility } from './MoveAbility'; - -/** - * Move function generic type param - */ -export type MoveFunctionGenericTypeParam = { - /** - * Move abilities tied to the generic type param and associated with the function that uses it - */ - constraints: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveFunctionVisibility.ts b/m1/JavaScript-client/src/generated/models/MoveFunctionVisibility.ts deleted file mode 100644 index a1684d5c8..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveFunctionVisibility.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Move function visibility - */ -export enum MoveFunctionVisibility { - PRIVATE = 'private', - PUBLIC = 'public', - FRIEND = 'friend', -} diff --git a/m1/JavaScript-client/src/generated/models/MoveModule.ts b/m1/JavaScript-client/src/generated/models/MoveModule.ts deleted file mode 100644 index f2d127ff2..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveModule.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { IdentifierWrapper } from './IdentifierWrapper'; -import type { MoveFunction } from './MoveFunction'; -import type { MoveModuleId } from './MoveModuleId'; -import type { MoveStruct } from './MoveStruct'; - -/** - * A Move module - */ -export type MoveModule = { - address: Address; - name: IdentifierWrapper; - /** - * Friends of the module - */ - friends: Array; - /** - * Public functions of the module - */ - exposed_functions: Array; - /** - * Structs of the module - */ - structs: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveModuleBytecode.ts b/m1/JavaScript-client/src/generated/models/MoveModuleBytecode.ts deleted file mode 100644 index 9348d1053..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveModuleBytecode.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HexEncodedBytes } from './HexEncodedBytes'; -import type { MoveModule } from './MoveModule'; - -/** - * Move module bytecode along with it's ABI - */ -export type MoveModuleBytecode = { - bytecode: HexEncodedBytes; - abi?: MoveModule; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveModuleId.ts b/m1/JavaScript-client/src/generated/models/MoveModuleId.ts deleted file mode 100644 index 5ad74349b..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveModuleId.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Move module id is a string representation of Move module. - * - * Format: `{address}::{module name}` - * - * `address` should be hex-encoded 32 byte account address that is prefixed with `0x`. - * - * Module name is case-sensitive. - * - */ -export type MoveModuleId = string; diff --git a/m1/JavaScript-client/src/generated/models/MoveResource.ts b/m1/JavaScript-client/src/generated/models/MoveResource.ts deleted file mode 100644 index 544bfa47b..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveResource.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MoveStructTag } from './MoveStructTag'; -import type { MoveStructValue } from './MoveStructValue'; - -/** - * A parsed Move resource - */ -export type MoveResource = { - type: MoveStructTag; - data: MoveStructValue; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveScriptBytecode.ts b/m1/JavaScript-client/src/generated/models/MoveScriptBytecode.ts deleted file mode 100644 index 109a6cf6b..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveScriptBytecode.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HexEncodedBytes } from './HexEncodedBytes'; -import type { MoveFunction } from './MoveFunction'; - -/** - * Move script bytecode - */ -export type MoveScriptBytecode = { - bytecode: HexEncodedBytes; - abi?: MoveFunction; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveStruct.ts b/m1/JavaScript-client/src/generated/models/MoveStruct.ts deleted file mode 100644 index 74dd1d876..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveStruct.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { IdentifierWrapper } from './IdentifierWrapper'; -import type { MoveAbility } from './MoveAbility'; -import type { MoveStructField } from './MoveStructField'; -import type { MoveStructGenericTypeParam } from './MoveStructGenericTypeParam'; - -/** - * A move struct - */ -export type MoveStruct = { - name: IdentifierWrapper; - /** - * Whether the struct is a native struct of Move - */ - is_native: boolean; - /** - * Abilities associated with the struct - */ - abilities: Array; - /** - * Generic types associated with the struct - */ - generic_type_params: Array; - /** - * Fields associated with the struct - */ - fields: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveStructField.ts b/m1/JavaScript-client/src/generated/models/MoveStructField.ts deleted file mode 100644 index 3f20b0bfb..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveStructField.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { IdentifierWrapper } from './IdentifierWrapper'; -import type { MoveType } from './MoveType'; - -/** - * Move struct field - */ -export type MoveStructField = { - name: IdentifierWrapper; - type: MoveType; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveStructGenericTypeParam.ts b/m1/JavaScript-client/src/generated/models/MoveStructGenericTypeParam.ts deleted file mode 100644 index 5ff3317db..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveStructGenericTypeParam.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MoveAbility } from './MoveAbility'; - -/** - * Move generic type param - */ -export type MoveStructGenericTypeParam = { - /** - * Move abilities tied to the generic type param and associated with the type that uses it - */ - constraints: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MoveStructTag.ts b/m1/JavaScript-client/src/generated/models/MoveStructTag.ts deleted file mode 100644 index 254235ddd..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveStructTag.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * String representation of a MoveStructTag (on-chain Move struct type). This exists so you - * can specify MoveStructTags as path / query parameters, e.g. for get_events_by_event_handle. - * - * It is a combination of: - * 1. `move_module_address`, `module_name` and `struct_name`, all joined by `::` - * 2. `struct generic type parameters` joined by `, ` - * - * Examples: - * * `0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>` - * * `0x1::account::Account` - * - * Note: - * 1. Empty chars should be ignored when comparing 2 struct tag ids. - * 2. When used in an URL path, should be encoded by url-encoding (AKA percent-encoding). - * - * See [doc](https://aptos.dev/concepts/accounts) for more details. - * - */ -export type MoveStructTag = string; diff --git a/m1/JavaScript-client/src/generated/models/MoveStructValue.ts b/m1/JavaScript-client/src/generated/models/MoveStructValue.ts deleted file mode 100644 index 11d4da457..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveStructValue.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * This is a JSON representation of some data within an account resource. More specifically, - * it is a map of strings to arbitrary JSON values / objects, where the keys are top level - * fields within the given resource. - * - * To clarify, you might query for 0x1::account::Account and see the example data. - * - * Move `bool` type value is serialized into `boolean`. - * - * Move `u8`, `u16` and `u32` type value is serialized into `integer`. - * - * Move `u64`, `u128` and `u256` type value is serialized into `string`. - * - * Move `address` type value (32 byte Aptos account address) is serialized into a HexEncodedBytes string. - * For example: - * - `0x1` - * - `0x1668f6be25668c1a17cd8caf6b8d2f25` - * - * Move `vector` type value is serialized into `array`, except `vector` which is serialized into a - * HexEncodedBytes string with `0x` prefix. - * For example: - * - `vector{255, 255}` => `["255", "255"]` - * - `vector{255, 255}` => `0xffff` - * - * Move `struct` type value is serialized into `object` that looks like this (except some Move stdlib types, see the following section): - * ```json - * { - * field1_name: field1_value, - * field2_name: field2_value, - * ...... - * } - * ``` - * - * For example: - * `{ "created": "0xa550c18", "role_id": "0" }` - * - * **Special serialization for Move stdlib types**: - * - [0x1::string::String](https://github.com/aptos-labs/aptos-core/blob/main/language/move-stdlib/docs/ascii.md) - * is serialized into `string`. For example, struct value `0x1::string::String{bytes: b"Hello World!"}` - * is serialized as `"Hello World!"` in JSON. - * - */ - export type MoveStructValue = { - }; - diff --git a/m1/JavaScript-client/src/generated/models/MoveType.ts b/m1/JavaScript-client/src/generated/models/MoveType.ts deleted file mode 100644 index 226183770..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveType.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * String representation of an on-chain Move type tag that is exposed in transaction payload. - * Values: - * - bool - * - u8 - * - u16 - * - u32 - * - u64 - * - u128 - * - u256 - * - address - * - signer - * - vector: `vector<{non-reference MoveTypeId}>` - * - struct: `{address}::{module_name}::{struct_name}::<{generic types}>` - * - * Vector type value examples: - * - `vector` - * - `vector>` - * - `vector<0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>>` - * - * Struct type value examples: - * - `0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin> - * - `0x1::account::Account` - * - * Note: - * 1. Empty chars should be ignored when comparing 2 struct tag ids. - * 2. When used in an URL path, should be encoded by url-encoding (AKA percent-encoding). - * - */ -export type MoveType = string; diff --git a/m1/JavaScript-client/src/generated/models/MoveValue.ts b/m1/JavaScript-client/src/generated/models/MoveValue.ts deleted file mode 100644 index 899490be8..000000000 --- a/m1/JavaScript-client/src/generated/models/MoveValue.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { HexEncodedBytes } from './HexEncodedBytes'; -import type { MoveStructValue } from './MoveStructValue'; -import type { U128 } from './U128'; -import type { U256 } from './U256'; -import type { U64 } from './U64'; - -/** - * An enum of the possible Move value types - */ -export type MoveValue = (number | U64 | U128 | U256 | boolean | Address | Array | HexEncodedBytes | MoveStructValue | string); - diff --git a/m1/JavaScript-client/src/generated/models/MultiAgentSignature.ts b/m1/JavaScript-client/src/generated/models/MultiAgentSignature.ts deleted file mode 100644 index f07b81734..000000000 --- a/m1/JavaScript-client/src/generated/models/MultiAgentSignature.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { AccountSignature } from './AccountSignature'; -import type { Address } from './Address'; - -/** - * Multi agent signature for multi agent transactions - * - * This allows you to have transactions across multiple accounts - */ -export type MultiAgentSignature = { - sender: AccountSignature; - /** - * The other involved parties' addresses - */ - secondary_signer_addresses: Array
; - /** - * The associated signatures, in the same order as the secondary addresses - */ - secondary_signers: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MultiEd25519Signature.ts b/m1/JavaScript-client/src/generated/models/MultiEd25519Signature.ts deleted file mode 100644 index 29809a29c..000000000 --- a/m1/JavaScript-client/src/generated/models/MultiEd25519Signature.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HexEncodedBytes } from './HexEncodedBytes'; - -/** - * A Ed25519 multi-sig signature - * - * This allows k-of-n signing for a transaction - */ -export type MultiEd25519Signature = { - /** - * The public keys for the Ed25519 signature - */ - public_keys: Array; - /** - * Signature associated with the public keys in the same order - */ - signatures: Array; - /** - * The number of signatures required for a successful transaction - */ - threshold: number; - bitmap: HexEncodedBytes; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MultisigPayload.ts b/m1/JavaScript-client/src/generated/models/MultisigPayload.ts deleted file mode 100644 index 9100a74b3..000000000 --- a/m1/JavaScript-client/src/generated/models/MultisigPayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { MultisigTransactionPayload } from './MultisigTransactionPayload'; - -/** - * A multisig transaction that allows an owner of a multisig account to execute a pre-approved - * transaction as the multisig account. - */ -export type MultisigPayload = { - multisig_address: Address; - transaction_payload?: MultisigTransactionPayload; -}; - diff --git a/m1/JavaScript-client/src/generated/models/MultisigTransactionPayload.ts b/m1/JavaScript-client/src/generated/models/MultisigTransactionPayload.ts deleted file mode 100644 index d3191b538..000000000 --- a/m1/JavaScript-client/src/generated/models/MultisigTransactionPayload.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EntryFunctionPayload } from './EntryFunctionPayload'; - -export type MultisigTransactionPayload = EntryFunctionPayload; - diff --git a/m1/JavaScript-client/src/generated/models/PendingTransaction.ts b/m1/JavaScript-client/src/generated/models/PendingTransaction.ts deleted file mode 100644 index 2b4ad87fd..000000000 --- a/m1/JavaScript-client/src/generated/models/PendingTransaction.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { HashValue } from './HashValue'; -import type { TransactionPayload } from './TransactionPayload'; -import type { TransactionSignature } from './TransactionSignature'; -import type { U64 } from './U64'; - -/** - * A transaction waiting in mempool - */ -export type PendingTransaction = { - hash: HashValue; - sender: Address; - sequence_number: U64; - max_gas_amount: U64; - gas_unit_price: U64; - expiration_timestamp_secs: U64; - payload: TransactionPayload; - signature?: TransactionSignature; -}; - diff --git a/m1/JavaScript-client/src/generated/models/RawTableItemRequest.ts b/m1/JavaScript-client/src/generated/models/RawTableItemRequest.ts deleted file mode 100644 index e8fc0f8ec..000000000 --- a/m1/JavaScript-client/src/generated/models/RawTableItemRequest.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HexEncodedBytes } from './HexEncodedBytes'; - -/** - * Table Item request for the GetTableItemRaw API - */ -export type RawTableItemRequest = { - key: HexEncodedBytes; -}; - diff --git a/m1/JavaScript-client/src/generated/models/RoleType.ts b/m1/JavaScript-client/src/generated/models/RoleType.ts deleted file mode 100644 index f0b5c207d..000000000 --- a/m1/JavaScript-client/src/generated/models/RoleType.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -export enum RoleType { - VALIDATOR = 'validator', - FULL_NODE = 'full_node', -} diff --git a/m1/JavaScript-client/src/generated/models/ScriptPayload.ts b/m1/JavaScript-client/src/generated/models/ScriptPayload.ts deleted file mode 100644 index 52cb0a057..000000000 --- a/m1/JavaScript-client/src/generated/models/ScriptPayload.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MoveScriptBytecode } from './MoveScriptBytecode'; -import type { MoveType } from './MoveType'; - -/** - * Payload which runs a script that can run multiple functions - */ -export type ScriptPayload = { - code: MoveScriptBytecode; - /** - * Type arguments of the function - */ - type_arguments: Array; - /** - * Arguments of the function - */ - arguments: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/ScriptWriteSet.ts b/m1/JavaScript-client/src/generated/models/ScriptWriteSet.ts deleted file mode 100644 index 469b78079..000000000 --- a/m1/JavaScript-client/src/generated/models/ScriptWriteSet.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { ScriptPayload } from './ScriptPayload'; - -export type ScriptWriteSet = { - execute_as: Address; - script: ScriptPayload; -}; - diff --git a/m1/JavaScript-client/src/generated/models/StateCheckpointTransaction.ts b/m1/JavaScript-client/src/generated/models/StateCheckpointTransaction.ts deleted file mode 100644 index bfe5b5dbc..000000000 --- a/m1/JavaScript-client/src/generated/models/StateCheckpointTransaction.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HashValue } from './HashValue'; -import type { U64 } from './U64'; -import type { WriteSetChange } from './WriteSetChange'; - -/** - * A state checkpoint transaction - */ -export type StateCheckpointTransaction = { - version: U64; - hash: HashValue; - state_change_hash: HashValue; - event_root_hash: HashValue; - state_checkpoint_hash?: HashValue; - gas_used: U64; - /** - * Whether the transaction was successful - */ - success: boolean; - /** - * The VM status of the transaction, can tell useful information in a failure - */ - vm_status: string; - accumulator_root_hash: HashValue; - /** - * Final state of resources changed by the transaction - */ - changes: Array; - timestamp: U64; -}; - diff --git a/m1/JavaScript-client/src/generated/models/StateKeyWrapper.ts b/m1/JavaScript-client/src/generated/models/StateKeyWrapper.ts deleted file mode 100644 index d3939a43e..000000000 --- a/m1/JavaScript-client/src/generated/models/StateKeyWrapper.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Representation of a StateKey as a hex string. This is used for cursor based pagination. - * - */ -export type StateKeyWrapper = string; diff --git a/m1/JavaScript-client/src/generated/models/SubmitTransactionRequest.ts b/m1/JavaScript-client/src/generated/models/SubmitTransactionRequest.ts deleted file mode 100644 index b850d3f54..000000000 --- a/m1/JavaScript-client/src/generated/models/SubmitTransactionRequest.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { TransactionPayload } from './TransactionPayload'; -import type { TransactionSignature } from './TransactionSignature'; -import type { U64 } from './U64'; - -/** - * A request to submit a transaction - * - * This requires a transaction and a signature of it - */ -export type SubmitTransactionRequest = { - sender: Address; - sequence_number: U64; - max_gas_amount: U64; - gas_unit_price: U64; - expiration_timestamp_secs: U64; - payload: TransactionPayload; - signature: TransactionSignature; -}; - diff --git a/m1/JavaScript-client/src/generated/models/TableItemRequest.ts b/m1/JavaScript-client/src/generated/models/TableItemRequest.ts deleted file mode 100644 index 18b44286d..000000000 --- a/m1/JavaScript-client/src/generated/models/TableItemRequest.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MoveType } from './MoveType'; - -/** - * Table Item request for the GetTableItem API - */ -export type TableItemRequest = { - key_type: MoveType; - value_type: MoveType; - /** - * The value of the table item's key - */ - key: any; -}; - diff --git a/m1/JavaScript-client/src/generated/models/Transaction.ts b/m1/JavaScript-client/src/generated/models/Transaction.ts deleted file mode 100644 index 0d6bd99e8..000000000 --- a/m1/JavaScript-client/src/generated/models/Transaction.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Transaction_BlockMetadataTransaction } from './Transaction_BlockMetadataTransaction'; -import type { Transaction_GenesisTransaction } from './Transaction_GenesisTransaction'; -import type { Transaction_PendingTransaction } from './Transaction_PendingTransaction'; -import type { Transaction_StateCheckpointTransaction } from './Transaction_StateCheckpointTransaction'; -import type { Transaction_UserTransaction } from './Transaction_UserTransaction'; - -/** - * Enum of the different types of transactions in Aptos - */ -export type Transaction = (Transaction_PendingTransaction | Transaction_UserTransaction | Transaction_GenesisTransaction | Transaction_BlockMetadataTransaction | Transaction_StateCheckpointTransaction); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionPayload.ts b/m1/JavaScript-client/src/generated/models/TransactionPayload.ts deleted file mode 100644 index 0115a2974..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionPayload.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { TransactionPayload_EntryFunctionPayload } from './TransactionPayload_EntryFunctionPayload'; -import type { TransactionPayload_ModuleBundlePayload } from './TransactionPayload_ModuleBundlePayload'; -import type { TransactionPayload_MultisigPayload } from './TransactionPayload_MultisigPayload'; -import type { TransactionPayload_ScriptPayload } from './TransactionPayload_ScriptPayload'; - -/** - * An enum of the possible transaction payloads - */ -export type TransactionPayload = (TransactionPayload_EntryFunctionPayload | TransactionPayload_ScriptPayload | TransactionPayload_ModuleBundlePayload | TransactionPayload_MultisigPayload); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionPayload_EntryFunctionPayload.ts b/m1/JavaScript-client/src/generated/models/TransactionPayload_EntryFunctionPayload.ts deleted file mode 100644 index d44e5d89a..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionPayload_EntryFunctionPayload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EntryFunctionPayload } from './EntryFunctionPayload'; - -export type TransactionPayload_EntryFunctionPayload = ({ - type: string; -} & EntryFunctionPayload); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionPayload_ModuleBundlePayload.ts b/m1/JavaScript-client/src/generated/models/TransactionPayload_ModuleBundlePayload.ts deleted file mode 100644 index 0193cb9d9..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionPayload_ModuleBundlePayload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ModuleBundlePayload } from './ModuleBundlePayload'; - -export type TransactionPayload_ModuleBundlePayload = ({ - type: string; -} & ModuleBundlePayload); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionPayload_MultisigPayload.ts b/m1/JavaScript-client/src/generated/models/TransactionPayload_MultisigPayload.ts deleted file mode 100644 index 01023dd71..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionPayload_MultisigPayload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MultisigPayload } from './MultisigPayload'; - -export type TransactionPayload_MultisigPayload = ({ - type: string; -} & MultisigPayload); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionPayload_ScriptPayload.ts b/m1/JavaScript-client/src/generated/models/TransactionPayload_ScriptPayload.ts deleted file mode 100644 index 9e7feb973..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionPayload_ScriptPayload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ScriptPayload } from './ScriptPayload'; - -export type TransactionPayload_ScriptPayload = ({ - type: string; -} & ScriptPayload); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionSignature.ts b/m1/JavaScript-client/src/generated/models/TransactionSignature.ts deleted file mode 100644 index b3861fbdb..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionSignature.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { TransactionSignature_Ed25519Signature } from './TransactionSignature_Ed25519Signature'; -import type { TransactionSignature_MultiAgentSignature } from './TransactionSignature_MultiAgentSignature'; -import type { TransactionSignature_MultiEd25519Signature } from './TransactionSignature_MultiEd25519Signature'; - -/** - * An enum representing the different transaction signatures available - */ -export type TransactionSignature = (TransactionSignature_Ed25519Signature | TransactionSignature_MultiEd25519Signature | TransactionSignature_MultiAgentSignature); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionSignature_Ed25519Signature.ts b/m1/JavaScript-client/src/generated/models/TransactionSignature_Ed25519Signature.ts deleted file mode 100644 index 0667d1e8b..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionSignature_Ed25519Signature.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Ed25519Signature } from './Ed25519Signature'; - -export type TransactionSignature_Ed25519Signature = ({ - type: string; -} & Ed25519Signature); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionSignature_MultiAgentSignature.ts b/m1/JavaScript-client/src/generated/models/TransactionSignature_MultiAgentSignature.ts deleted file mode 100644 index e74d911d9..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionSignature_MultiAgentSignature.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MultiAgentSignature } from './MultiAgentSignature'; - -export type TransactionSignature_MultiAgentSignature = ({ - type: string; -} & MultiAgentSignature); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionSignature_MultiEd25519Signature.ts b/m1/JavaScript-client/src/generated/models/TransactionSignature_MultiEd25519Signature.ts deleted file mode 100644 index 1f6dc58ad..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionSignature_MultiEd25519Signature.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { MultiEd25519Signature } from './MultiEd25519Signature'; - -export type TransactionSignature_MultiEd25519Signature = ({ - type: string; -} & MultiEd25519Signature); - diff --git a/m1/JavaScript-client/src/generated/models/Transaction_BlockMetadataTransaction.ts b/m1/JavaScript-client/src/generated/models/Transaction_BlockMetadataTransaction.ts deleted file mode 100644 index 82067d747..000000000 --- a/m1/JavaScript-client/src/generated/models/Transaction_BlockMetadataTransaction.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { BlockMetadataTransaction } from './BlockMetadataTransaction'; - -export type Transaction_BlockMetadataTransaction = ({ - type: string; -} & BlockMetadataTransaction); - diff --git a/m1/JavaScript-client/src/generated/models/Transaction_GenesisTransaction.ts b/m1/JavaScript-client/src/generated/models/Transaction_GenesisTransaction.ts deleted file mode 100644 index 3bb44fd02..000000000 --- a/m1/JavaScript-client/src/generated/models/Transaction_GenesisTransaction.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { GenesisTransaction } from './GenesisTransaction'; - -export type Transaction_GenesisTransaction = ({ - type: string; -} & GenesisTransaction); - diff --git a/m1/JavaScript-client/src/generated/models/Transaction_PendingTransaction.ts b/m1/JavaScript-client/src/generated/models/Transaction_PendingTransaction.ts deleted file mode 100644 index c593c7642..000000000 --- a/m1/JavaScript-client/src/generated/models/Transaction_PendingTransaction.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { PendingTransaction } from './PendingTransaction'; - -export type Transaction_PendingTransaction = ({ - type: string; -} & PendingTransaction); - diff --git a/m1/JavaScript-client/src/generated/models/Transaction_StateCheckpointTransaction.ts b/m1/JavaScript-client/src/generated/models/Transaction_StateCheckpointTransaction.ts deleted file mode 100644 index 90eeda700..000000000 --- a/m1/JavaScript-client/src/generated/models/Transaction_StateCheckpointTransaction.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { StateCheckpointTransaction } from './StateCheckpointTransaction'; - -export type Transaction_StateCheckpointTransaction = ({ - type: string; -} & StateCheckpointTransaction); - diff --git a/m1/JavaScript-client/src/generated/models/Transaction_UserTransaction.ts b/m1/JavaScript-client/src/generated/models/Transaction_UserTransaction.ts deleted file mode 100644 index 8feeed7c2..000000000 --- a/m1/JavaScript-client/src/generated/models/Transaction_UserTransaction.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { UserTransaction } from './UserTransaction'; - -export type Transaction_UserTransaction = ({ - type: string; -} & UserTransaction); - diff --git a/m1/JavaScript-client/src/generated/models/TransactionsBatchSingleSubmissionFailure.ts b/m1/JavaScript-client/src/generated/models/TransactionsBatchSingleSubmissionFailure.ts deleted file mode 100644 index 98f81af61..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionsBatchSingleSubmissionFailure.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { AptosError } from './AptosError'; - -/** - * Information telling which batch submission transactions failed - */ -export type TransactionsBatchSingleSubmissionFailure = { - error: AptosError; - /** - * The index of which transaction failed, same as submission order - */ - transaction_index: number; -}; - diff --git a/m1/JavaScript-client/src/generated/models/TransactionsBatchSubmissionResult.ts b/m1/JavaScript-client/src/generated/models/TransactionsBatchSubmissionResult.ts deleted file mode 100644 index 43c5d62f8..000000000 --- a/m1/JavaScript-client/src/generated/models/TransactionsBatchSubmissionResult.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { TransactionsBatchSingleSubmissionFailure } from './TransactionsBatchSingleSubmissionFailure'; - -/** - * Batch transaction submission result - * - * Tells which transactions failed - */ -export type TransactionsBatchSubmissionResult = { - /** - * Summary of the failed transactions - */ - transaction_failures: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/U128.ts b/m1/JavaScript-client/src/generated/models/U128.ts deleted file mode 100644 index d391d4afb..000000000 --- a/m1/JavaScript-client/src/generated/models/U128.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * A string containing a 128-bit unsigned integer. - * - * We represent u128 values as a string to ensure compatibility with languages such - * as JavaScript that do not parse u128s in JSON natively. - * - */ -export type U128 = string; diff --git a/m1/JavaScript-client/src/generated/models/U256.ts b/m1/JavaScript-client/src/generated/models/U256.ts deleted file mode 100644 index 092d56d8e..000000000 --- a/m1/JavaScript-client/src/generated/models/U256.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * A string containing a 256-bit unsigned integer. - * - * We represent u256 values as a string to ensure compatibility with languages such - * as JavaScript that do not parse u256s in JSON natively. - * - */ -export type U256 = string; diff --git a/m1/JavaScript-client/src/generated/models/U64.ts b/m1/JavaScript-client/src/generated/models/U64.ts deleted file mode 100644 index f8f542c60..000000000 --- a/m1/JavaScript-client/src/generated/models/U64.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * A string containing a 64-bit unsigned integer. - * - * We represent u64 values as a string to ensure compatibility with languages such - * as JavaScript that do not parse u64s in JSON natively. - * - */ -export type U64 = string; diff --git a/m1/JavaScript-client/src/generated/models/UserTransaction.ts b/m1/JavaScript-client/src/generated/models/UserTransaction.ts deleted file mode 100644 index 4aa4e67a3..000000000 --- a/m1/JavaScript-client/src/generated/models/UserTransaction.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { Event } from './Event'; -import type { HashValue } from './HashValue'; -import type { TransactionPayload } from './TransactionPayload'; -import type { TransactionSignature } from './TransactionSignature'; -import type { U64 } from './U64'; -import type { WriteSetChange } from './WriteSetChange'; - -/** - * A transaction submitted by a user to change the state of the blockchain - */ -export type UserTransaction = { - version: U64; - hash: HashValue; - state_change_hash: HashValue; - event_root_hash: HashValue; - state_checkpoint_hash?: HashValue; - gas_used: U64; - /** - * Whether the transaction was successful - */ - success: boolean; - /** - * The VM status of the transaction, can tell useful information in a failure - */ - vm_status: string; - accumulator_root_hash: HashValue; - /** - * Final state of resources changed by the transaction - */ - changes: Array; - sender: Address; - sequence_number: U64; - max_gas_amount: U64; - gas_unit_price: U64; - expiration_timestamp_secs: U64; - payload: TransactionPayload; - signature?: TransactionSignature; - /** - * Events generated by the transaction - */ - events: Array; - timestamp: U64; -}; - diff --git a/m1/JavaScript-client/src/generated/models/VersionedEvent.ts b/m1/JavaScript-client/src/generated/models/VersionedEvent.ts deleted file mode 100644 index c9934c820..000000000 --- a/m1/JavaScript-client/src/generated/models/VersionedEvent.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EventGuid } from './EventGuid'; -import type { MoveType } from './MoveType'; -import type { U64 } from './U64'; - -/** - * An event from a transaction with a version - */ -export type VersionedEvent = { - version: U64; - guid: EventGuid; - sequence_number: U64; - type: MoveType; - /** - * The JSON representation of the event - */ - data: any; -}; - diff --git a/m1/JavaScript-client/src/generated/models/ViewRequest.ts b/m1/JavaScript-client/src/generated/models/ViewRequest.ts deleted file mode 100644 index 5fa124b8e..000000000 --- a/m1/JavaScript-client/src/generated/models/ViewRequest.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EntryFunctionId } from './EntryFunctionId'; -import type { MoveType } from './MoveType'; - -/** - * View request for the Move View Function API - */ -export type ViewRequest = { - function: EntryFunctionId; - /** - * Type arguments of the function - */ - type_arguments: Array; - /** - * Arguments of the function - */ - arguments: Array; -}; - diff --git a/m1/JavaScript-client/src/generated/models/WriteModule.ts b/m1/JavaScript-client/src/generated/models/WriteModule.ts deleted file mode 100644 index b032cc913..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteModule.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { MoveModuleBytecode } from './MoveModuleBytecode'; - -/** - * Write a new module or update an existing one - */ -export type WriteModule = { - address: Address; - /** - * State key hash - */ - state_key_hash: string; - data: MoveModuleBytecode; -}; - diff --git a/m1/JavaScript-client/src/generated/models/WriteResource.ts b/m1/JavaScript-client/src/generated/models/WriteResource.ts deleted file mode 100644 index 2bccf200e..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteResource.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { Address } from './Address'; -import type { MoveResource } from './MoveResource'; - -/** - * Write a resource or update an existing one - */ -export type WriteResource = { - address: Address; - /** - * State key hash - */ - state_key_hash: string; - data: MoveResource; -}; - diff --git a/m1/JavaScript-client/src/generated/models/WriteSet.ts b/m1/JavaScript-client/src/generated/models/WriteSet.ts deleted file mode 100644 index ea06d3e63..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSet.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { WriteSet_DirectWriteSet } from './WriteSet_DirectWriteSet'; -import type { WriteSet_ScriptWriteSet } from './WriteSet_ScriptWriteSet'; - -/** - * The associated writeset with a payload - */ -export type WriteSet = (WriteSet_ScriptWriteSet | WriteSet_DirectWriteSet); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetChange.ts b/m1/JavaScript-client/src/generated/models/WriteSetChange.ts deleted file mode 100644 index dfcc2cb63..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetChange.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { WriteSetChange_DeleteModule } from './WriteSetChange_DeleteModule'; -import type { WriteSetChange_DeleteResource } from './WriteSetChange_DeleteResource'; -import type { WriteSetChange_DeleteTableItem } from './WriteSetChange_DeleteTableItem'; -import type { WriteSetChange_WriteModule } from './WriteSetChange_WriteModule'; -import type { WriteSetChange_WriteResource } from './WriteSetChange_WriteResource'; -import type { WriteSetChange_WriteTableItem } from './WriteSetChange_WriteTableItem'; - -/** - * A final state change of a transaction on a resource or module - */ -export type WriteSetChange = (WriteSetChange_DeleteModule | WriteSetChange_DeleteResource | WriteSetChange_DeleteTableItem | WriteSetChange_WriteModule | WriteSetChange_WriteResource | WriteSetChange_WriteTableItem); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteModule.ts b/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteModule.ts deleted file mode 100644 index 3c4252969..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteModule.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DeleteModule } from './DeleteModule'; - -export type WriteSetChange_DeleteModule = ({ - type: string; -} & DeleteModule); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteResource.ts b/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteResource.ts deleted file mode 100644 index bfb9924b6..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteResource.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DeleteResource } from './DeleteResource'; - -export type WriteSetChange_DeleteResource = ({ - type: string; -} & DeleteResource); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteTableItem.ts b/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteTableItem.ts deleted file mode 100644 index d82340222..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetChange_DeleteTableItem.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DeleteTableItem } from './DeleteTableItem'; - -export type WriteSetChange_DeleteTableItem = ({ - type: string; -} & DeleteTableItem); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteModule.ts b/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteModule.ts deleted file mode 100644 index 924d279b8..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteModule.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { WriteModule } from './WriteModule'; - -export type WriteSetChange_WriteModule = ({ - type: string; -} & WriteModule); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteResource.ts b/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteResource.ts deleted file mode 100644 index e7d4f6be5..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteResource.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { WriteResource } from './WriteResource'; - -export type WriteSetChange_WriteResource = ({ - type: string; -} & WriteResource); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteTableItem.ts b/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteTableItem.ts deleted file mode 100644 index 087c9765a..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetChange_WriteTableItem.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { WriteTableItem } from './WriteTableItem'; - -export type WriteSetChange_WriteTableItem = ({ - type: string; -} & WriteTableItem); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSetPayload.ts b/m1/JavaScript-client/src/generated/models/WriteSetPayload.ts deleted file mode 100644 index c15ea62f2..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSetPayload.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { WriteSet } from './WriteSet'; - -/** - * A writeset payload, used only for genesis - */ -export type WriteSetPayload = { - write_set: WriteSet; -}; - diff --git a/m1/JavaScript-client/src/generated/models/WriteSet_DirectWriteSet.ts b/m1/JavaScript-client/src/generated/models/WriteSet_DirectWriteSet.ts deleted file mode 100644 index 552e98d48..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSet_DirectWriteSet.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DirectWriteSet } from './DirectWriteSet'; - -export type WriteSet_DirectWriteSet = ({ - type: string; -} & DirectWriteSet); - diff --git a/m1/JavaScript-client/src/generated/models/WriteSet_ScriptWriteSet.ts b/m1/JavaScript-client/src/generated/models/WriteSet_ScriptWriteSet.ts deleted file mode 100644 index e7304a8a8..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteSet_ScriptWriteSet.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ScriptWriteSet } from './ScriptWriteSet'; - -export type WriteSet_ScriptWriteSet = ({ - type: string; -} & ScriptWriteSet); - diff --git a/m1/JavaScript-client/src/generated/models/WriteTableItem.ts b/m1/JavaScript-client/src/generated/models/WriteTableItem.ts deleted file mode 100644 index 6fbaa2b02..000000000 --- a/m1/JavaScript-client/src/generated/models/WriteTableItem.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DecodedTableData } from './DecodedTableData'; -import type { HexEncodedBytes } from './HexEncodedBytes'; - -/** - * Change set to write a table item - */ -export type WriteTableItem = { - state_key_hash: string; - handle: HexEncodedBytes; - key: HexEncodedBytes; - value: HexEncodedBytes; - data?: DecodedTableData; -}; - diff --git a/m1/JavaScript-client/src/generated/schemas/$AccountData.ts b/m1/JavaScript-client/src/generated/schemas/$AccountData.ts deleted file mode 100644 index 04582cd5e..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$AccountData.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $AccountData = { - description: `Account data - - A simplified version of the onchain Account resource`, - properties: { - sequence_number: { - type: 'U64', - isRequired: true, - }, - authentication_key: { - type: 'HexEncodedBytes', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$AccountSignature.ts b/m1/JavaScript-client/src/generated/schemas/$AccountSignature.ts deleted file mode 100644 index 2a36b5d67..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$AccountSignature.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $AccountSignature = { - type: 'one-of', - description: `Account signature scheme - - The account signature scheme allows you to have two types of accounts: - - 1. A single Ed25519 key account, one private key - 2. A k-of-n multi-Ed25519 key account, multiple private keys, such that k-of-n must sign a transaction.`, - contains: [{ - type: 'AccountSignature_Ed25519Signature', - }, { - type: 'AccountSignature_MultiEd25519Signature', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$AccountSignature_Ed25519Signature.ts b/m1/JavaScript-client/src/generated/schemas/$AccountSignature_Ed25519Signature.ts deleted file mode 100644 index 2a16d8b91..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$AccountSignature_Ed25519Signature.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $AccountSignature_Ed25519Signature = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'Ed25519Signature', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$AccountSignature_MultiEd25519Signature.ts b/m1/JavaScript-client/src/generated/schemas/$AccountSignature_MultiEd25519Signature.ts deleted file mode 100644 index 73d0cfed8..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$AccountSignature_MultiEd25519Signature.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $AccountSignature_MultiEd25519Signature = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'MultiEd25519Signature', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Address.ts b/m1/JavaScript-client/src/generated/schemas/$Address.ts deleted file mode 100644 index 0e5400c7c..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Address.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Address = { - type: 'string', - description: `A hex encoded 32 byte Aptos account address. - - This is represented in a string as a 64 character hex string, sometimes - shortened by stripping leading 0s, and adding a 0x. - - For example, address 0x0000000000000000000000000000000000000000000000000000000000000001 is represented as 0x1. - `, - format: 'hex', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$AptosError.ts b/m1/JavaScript-client/src/generated/schemas/$AptosError.ts deleted file mode 100644 index 72390bbcb..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$AptosError.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $AptosError = { - description: `This is the generic struct we use for all API errors, it contains a string - message and an Aptos API specific error code.`, - properties: { - message: { - type: 'string', - description: `A message describing the error`, - isRequired: true, - }, - error_code: { - type: 'AptosErrorCode', - isRequired: true, - }, - vm_error_code: { - type: 'number', - description: `A code providing VM error details when submitting transactions to the VM`, - format: 'uint64', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$AptosErrorCode.ts b/m1/JavaScript-client/src/generated/schemas/$AptosErrorCode.ts deleted file mode 100644 index 57dc2d105..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$AptosErrorCode.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $AptosErrorCode = { - type: 'Enum', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Block.ts b/m1/JavaScript-client/src/generated/schemas/$Block.ts deleted file mode 100644 index 970ba6106..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Block.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Block = { - description: `A Block with or without transactions - - This contains the information about a transactions along with - associated transactions if requested`, - properties: { - block_height: { - type: 'U64', - isRequired: true, - }, - block_hash: { - type: 'HashValue', - isRequired: true, - }, - block_timestamp: { - type: 'U64', - isRequired: true, - }, - first_version: { - type: 'U64', - isRequired: true, - }, - last_version: { - type: 'U64', - isRequired: true, - }, - transactions: { - type: 'array', - contains: { - type: 'Transaction', - }, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$BlockMetadataTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$BlockMetadataTransaction.ts deleted file mode 100644 index 434bf4eab..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$BlockMetadataTransaction.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $BlockMetadataTransaction = { - description: `A block metadata transaction - - This signifies the beginning of a block, and contains information - about the specific block`, - properties: { - version: { - type: 'U64', - isRequired: true, - }, - hash: { - type: 'HashValue', - isRequired: true, - }, - state_change_hash: { - type: 'HashValue', - isRequired: true, - }, - event_root_hash: { - type: 'HashValue', - isRequired: true, - }, - state_checkpoint_hash: { - type: 'HashValue', - }, - gas_used: { - type: 'U64', - isRequired: true, - }, - success: { - type: 'boolean', - description: `Whether the transaction was successful`, - isRequired: true, - }, - vm_status: { - type: 'string', - description: `The VM status of the transaction, can tell useful information in a failure`, - isRequired: true, - }, - accumulator_root_hash: { - type: 'HashValue', - isRequired: true, - }, - changes: { - type: 'array', - contains: { - type: 'WriteSetChange', - }, - isRequired: true, - }, - id: { - type: 'HashValue', - isRequired: true, - }, - epoch: { - type: 'U64', - isRequired: true, - }, - round: { - type: 'U64', - isRequired: true, - }, - events: { - type: 'array', - contains: { - type: 'Event', - }, - isRequired: true, - }, - previous_block_votes_bitvec: { - type: 'array', - contains: { - type: 'number', - format: 'uint8', - }, - isRequired: true, - }, - proposer: { - type: 'Address', - isRequired: true, - }, - failed_proposer_indices: { - type: 'array', - contains: { - type: 'number', - format: 'uint32', - }, - isRequired: true, - }, - timestamp: { - type: 'U64', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$DecodedTableData.ts b/m1/JavaScript-client/src/generated/schemas/$DecodedTableData.ts deleted file mode 100644 index 75bd13d27..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$DecodedTableData.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $DecodedTableData = { - description: `Decoded table data`, - properties: { - key: { - description: `Key of table in JSON`, - properties: { - }, - isRequired: true, - }, - key_type: { - type: 'string', - description: `Type of key`, - isRequired: true, - }, - value: { - description: `Value of table in JSON`, - properties: { - }, - isRequired: true, - }, - value_type: { - type: 'string', - description: `Type of value`, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$DeleteModule.ts b/m1/JavaScript-client/src/generated/schemas/$DeleteModule.ts deleted file mode 100644 index e9c4c7fb1..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$DeleteModule.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $DeleteModule = { - description: `Delete a module`, - properties: { - address: { - type: 'Address', - isRequired: true, - }, - state_key_hash: { - type: 'string', - description: `State key hash`, - isRequired: true, - }, - module: { - type: 'MoveModuleId', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$DeleteResource.ts b/m1/JavaScript-client/src/generated/schemas/$DeleteResource.ts deleted file mode 100644 index 61e39a709..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$DeleteResource.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $DeleteResource = { - description: `Delete a resource`, - properties: { - address: { - type: 'Address', - isRequired: true, - }, - state_key_hash: { - type: 'string', - description: `State key hash`, - isRequired: true, - }, - resource: { - type: 'MoveStructTag', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$DeleteTableItem.ts b/m1/JavaScript-client/src/generated/schemas/$DeleteTableItem.ts deleted file mode 100644 index 1e6412633..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$DeleteTableItem.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $DeleteTableItem = { - description: `Delete a table item`, - properties: { - state_key_hash: { - type: 'string', - isRequired: true, - }, - handle: { - type: 'HexEncodedBytes', - isRequired: true, - }, - key: { - type: 'HexEncodedBytes', - isRequired: true, - }, - data: { - type: 'DeletedTableData', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$DeletedTableData.ts b/m1/JavaScript-client/src/generated/schemas/$DeletedTableData.ts deleted file mode 100644 index c617e3b9f..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$DeletedTableData.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $DeletedTableData = { - description: `Deleted table data`, - properties: { - key: { - description: `Deleted key`, - properties: { - }, - isRequired: true, - }, - key_type: { - type: 'string', - description: `Deleted key type`, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$DirectWriteSet.ts b/m1/JavaScript-client/src/generated/schemas/$DirectWriteSet.ts deleted file mode 100644 index fc121ffea..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$DirectWriteSet.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $DirectWriteSet = { - properties: { - changes: { - type: 'array', - contains: { - type: 'WriteSetChange', - }, - isRequired: true, - }, - events: { - type: 'array', - contains: { - type: 'Event', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Ed25519Signature.ts b/m1/JavaScript-client/src/generated/schemas/$Ed25519Signature.ts deleted file mode 100644 index c1a87faad..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Ed25519Signature.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Ed25519Signature = { - description: `A single Ed25519 signature`, - properties: { - public_key: { - type: 'HexEncodedBytes', - isRequired: true, - }, - signature: { - type: 'HexEncodedBytes', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$EncodeSubmissionRequest.ts b/m1/JavaScript-client/src/generated/schemas/$EncodeSubmissionRequest.ts deleted file mode 100644 index f27f97993..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$EncodeSubmissionRequest.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $EncodeSubmissionRequest = { - description: `Request to encode a submission`, - properties: { - sender: { - type: 'Address', - isRequired: true, - }, - sequence_number: { - type: 'U64', - isRequired: true, - }, - max_gas_amount: { - type: 'U64', - isRequired: true, - }, - gas_unit_price: { - type: 'U64', - isRequired: true, - }, - expiration_timestamp_secs: { - type: 'U64', - isRequired: true, - }, - payload: { - type: 'TransactionPayload', - isRequired: true, - }, - secondary_signers: { - type: 'array', - contains: { - type: 'Address', - }, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$EntryFunctionId.ts b/m1/JavaScript-client/src/generated/schemas/$EntryFunctionId.ts deleted file mode 100644 index 7e1f80c07..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$EntryFunctionId.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $EntryFunctionId = { - type: 'string', - description: `Entry function id is string representation of a entry function defined on-chain. - - Format: \`{address}::{module name}::{function name}\` - - Both \`module name\` and \`function name\` are case-sensitive. - `, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$EntryFunctionPayload.ts b/m1/JavaScript-client/src/generated/schemas/$EntryFunctionPayload.ts deleted file mode 100644 index 4cdddc0aa..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$EntryFunctionPayload.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $EntryFunctionPayload = { - description: `Payload which runs a single entry function`, - properties: { - function: { - type: 'EntryFunctionId', - isRequired: true, - }, - type_arguments: { - type: 'array', - contains: { - type: 'MoveType', - }, - isRequired: true, - }, - arguments: { - type: 'array', - contains: { - properties: { - }, - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Event.ts b/m1/JavaScript-client/src/generated/schemas/$Event.ts deleted file mode 100644 index 83b84ca12..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Event.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Event = { - description: `An event from a transaction`, - properties: { - guid: { - type: 'EventGuid', - isRequired: true, - }, - sequence_number: { - type: 'U64', - isRequired: true, - }, - type: { - type: 'MoveType', - isRequired: true, - }, - data: { - description: `The JSON representation of the event`, - properties: { - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$EventGuid.ts b/m1/JavaScript-client/src/generated/schemas/$EventGuid.ts deleted file mode 100644 index 773e5b9a9..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$EventGuid.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $EventGuid = { - properties: { - creation_number: { - type: 'U64', - isRequired: true, - }, - account_address: { - type: 'Address', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$GasEstimation.ts b/m1/JavaScript-client/src/generated/schemas/$GasEstimation.ts deleted file mode 100644 index 22dc555dc..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$GasEstimation.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $GasEstimation = { - description: `Struct holding the outputs of the estimate gas API`, - properties: { - deprioritized_gas_estimate: { - type: 'number', - description: `The deprioritized estimate for the gas unit price`, - format: 'uint64', - }, - gas_estimate: { - type: 'number', - description: `The current estimate for the gas unit price`, - isRequired: true, - format: 'uint64', - }, - prioritized_gas_estimate: { - type: 'number', - description: `The prioritized estimate for the gas unit price`, - format: 'uint64', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$GenesisPayload.ts b/m1/JavaScript-client/src/generated/schemas/$GenesisPayload.ts deleted file mode 100644 index bbc3ca1bd..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$GenesisPayload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $GenesisPayload = { - type: 'one-of', - description: `The writeset payload of the Genesis transaction`, - contains: [{ - type: 'GenesisPayload_WriteSetPayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$GenesisPayload_WriteSetPayload.ts b/m1/JavaScript-client/src/generated/schemas/$GenesisPayload_WriteSetPayload.ts deleted file mode 100644 index 4d81069d3..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$GenesisPayload_WriteSetPayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $GenesisPayload_WriteSetPayload = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'WriteSetPayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$GenesisTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$GenesisTransaction.ts deleted file mode 100644 index 96846f1fd..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$GenesisTransaction.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $GenesisTransaction = { - description: `The genesis transaction - - This only occurs at the genesis transaction (version 0)`, - properties: { - version: { - type: 'U64', - isRequired: true, - }, - hash: { - type: 'HashValue', - isRequired: true, - }, - state_change_hash: { - type: 'HashValue', - isRequired: true, - }, - event_root_hash: { - type: 'HashValue', - isRequired: true, - }, - state_checkpoint_hash: { - type: 'HashValue', - }, - gas_used: { - type: 'U64', - isRequired: true, - }, - success: { - type: 'boolean', - description: `Whether the transaction was successful`, - isRequired: true, - }, - vm_status: { - type: 'string', - description: `The VM status of the transaction, can tell useful information in a failure`, - isRequired: true, - }, - accumulator_root_hash: { - type: 'HashValue', - isRequired: true, - }, - changes: { - type: 'array', - contains: { - type: 'WriteSetChange', - }, - isRequired: true, - }, - payload: { - type: 'GenesisPayload', - isRequired: true, - }, - events: { - type: 'array', - contains: { - type: 'Event', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$HashValue.ts b/m1/JavaScript-client/src/generated/schemas/$HashValue.ts deleted file mode 100644 index 69bc6ed19..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$HashValue.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $HashValue = { - type: 'string', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$HealthCheckSuccess.ts b/m1/JavaScript-client/src/generated/schemas/$HealthCheckSuccess.ts deleted file mode 100644 index bb42237d6..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$HealthCheckSuccess.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $HealthCheckSuccess = { - description: `Representation of a successful healthcheck`, - properties: { - message: { - type: 'string', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$HexEncodedBytes.ts b/m1/JavaScript-client/src/generated/schemas/$HexEncodedBytes.ts deleted file mode 100644 index 69282bbad..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$HexEncodedBytes.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $HexEncodedBytes = { - type: 'string', - description: `All bytes (Vec) data is represented as hex-encoded string prefixed with \`0x\` and fulfilled with - two hex digits per byte. - - Unlike the \`Address\` type, HexEncodedBytes will not trim any zeros. - `, - format: 'hex', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$IdentifierWrapper.ts b/m1/JavaScript-client/src/generated/schemas/$IdentifierWrapper.ts deleted file mode 100644 index b139a50fc..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$IdentifierWrapper.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $IdentifierWrapper = { - type: 'string', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$IndexResponse.ts b/m1/JavaScript-client/src/generated/schemas/$IndexResponse.ts deleted file mode 100644 index a9e1f9cfa..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$IndexResponse.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $IndexResponse = { - description: `The struct holding all data returned to the client by the - index endpoint (i.e., GET "/"). Only for responding in JSON`, - properties: { - chain_id: { - type: 'number', - description: `Chain ID of the current chain`, - isRequired: true, - format: 'uint8', - }, - epoch: { - type: 'U64', - isRequired: true, - }, - ledger_version: { - type: 'U64', - isRequired: true, - }, - oldest_ledger_version: { - type: 'U64', - isRequired: true, - }, - ledger_timestamp: { - type: 'U64', - isRequired: true, - }, - node_role: { - type: 'RoleType', - isRequired: true, - }, - oldest_block_height: { - type: 'U64', - isRequired: true, - }, - block_height: { - type: 'U64', - isRequired: true, - }, - git_hash: { - type: 'string', - description: `Git hash of the build of the API endpoint. Can be used to determine the exact - software version used by the API endpoint.`, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$ModuleBundlePayload.ts b/m1/JavaScript-client/src/generated/schemas/$ModuleBundlePayload.ts deleted file mode 100644 index 714ba9aac..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$ModuleBundlePayload.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $ModuleBundlePayload = { - properties: { - modules: { - type: 'array', - contains: { - type: 'MoveModuleBytecode', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveAbility.ts b/m1/JavaScript-client/src/generated/schemas/$MoveAbility.ts deleted file mode 100644 index 40c3cd3c0..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveAbility.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveAbility = { - type: 'string', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveFunction.ts b/m1/JavaScript-client/src/generated/schemas/$MoveFunction.ts deleted file mode 100644 index a813733b7..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveFunction.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveFunction = { - description: `Move function`, - properties: { - name: { - type: 'IdentifierWrapper', - isRequired: true, - }, - visibility: { - type: 'MoveFunctionVisibility', - isRequired: true, - }, - is_entry: { - type: 'boolean', - description: `Whether the function can be called as an entry function directly in a transaction`, - isRequired: true, - }, - is_view: { - type: 'boolean', - description: `Whether the function is a view function or not`, - isRequired: true, - }, - generic_type_params: { - type: 'array', - contains: { - type: 'MoveFunctionGenericTypeParam', - }, - isRequired: true, - }, - params: { - type: 'array', - contains: { - type: 'MoveType', - }, - isRequired: true, - }, - return: { - type: 'array', - contains: { - type: 'MoveType', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveFunctionGenericTypeParam.ts b/m1/JavaScript-client/src/generated/schemas/$MoveFunctionGenericTypeParam.ts deleted file mode 100644 index 9d739aacd..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveFunctionGenericTypeParam.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveFunctionGenericTypeParam = { - description: `Move function generic type param`, - properties: { - constraints: { - type: 'array', - contains: { - type: 'MoveAbility', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveFunctionVisibility.ts b/m1/JavaScript-client/src/generated/schemas/$MoveFunctionVisibility.ts deleted file mode 100644 index 25ea8043c..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveFunctionVisibility.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveFunctionVisibility = { - type: 'Enum', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveModule.ts b/m1/JavaScript-client/src/generated/schemas/$MoveModule.ts deleted file mode 100644 index 38a42525a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveModule.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveModule = { - description: `A Move module`, - properties: { - address: { - type: 'Address', - isRequired: true, - }, - name: { - type: 'IdentifierWrapper', - isRequired: true, - }, - friends: { - type: 'array', - contains: { - type: 'MoveModuleId', - }, - isRequired: true, - }, - exposed_functions: { - type: 'array', - contains: { - type: 'MoveFunction', - }, - isRequired: true, - }, - structs: { - type: 'array', - contains: { - type: 'MoveStruct', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveModuleBytecode.ts b/m1/JavaScript-client/src/generated/schemas/$MoveModuleBytecode.ts deleted file mode 100644 index 801d994ec..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveModuleBytecode.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveModuleBytecode = { - description: `Move module bytecode along with it's ABI`, - properties: { - bytecode: { - type: 'HexEncodedBytes', - isRequired: true, - }, - abi: { - type: 'MoveModule', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveModuleId.ts b/m1/JavaScript-client/src/generated/schemas/$MoveModuleId.ts deleted file mode 100644 index 338679c7a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveModuleId.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveModuleId = { - type: 'string', - description: `Move module id is a string representation of Move module. - - Format: \`{address}::{module name}\` - - \`address\` should be hex-encoded 32 byte account address that is prefixed with \`0x\`. - - Module name is case-sensitive. - `, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveResource.ts b/m1/JavaScript-client/src/generated/schemas/$MoveResource.ts deleted file mode 100644 index e1abb5a01..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveResource.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveResource = { - description: `A parsed Move resource`, - properties: { - type: { - type: 'MoveStructTag', - isRequired: true, - }, - data: { - type: 'MoveStructValue', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveScriptBytecode.ts b/m1/JavaScript-client/src/generated/schemas/$MoveScriptBytecode.ts deleted file mode 100644 index 3951245ac..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveScriptBytecode.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveScriptBytecode = { - description: `Move script bytecode`, - properties: { - bytecode: { - type: 'HexEncodedBytes', - isRequired: true, - }, - abi: { - type: 'MoveFunction', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveStruct.ts b/m1/JavaScript-client/src/generated/schemas/$MoveStruct.ts deleted file mode 100644 index 8d79ad36c..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveStruct.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveStruct = { - description: `A move struct`, - properties: { - name: { - type: 'IdentifierWrapper', - isRequired: true, - }, - is_native: { - type: 'boolean', - description: `Whether the struct is a native struct of Move`, - isRequired: true, - }, - abilities: { - type: 'array', - contains: { - type: 'MoveAbility', - }, - isRequired: true, - }, - generic_type_params: { - type: 'array', - contains: { - type: 'MoveStructGenericTypeParam', - }, - isRequired: true, - }, - fields: { - type: 'array', - contains: { - type: 'MoveStructField', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveStructField.ts b/m1/JavaScript-client/src/generated/schemas/$MoveStructField.ts deleted file mode 100644 index 7ab94104a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveStructField.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveStructField = { - description: `Move struct field`, - properties: { - name: { - type: 'IdentifierWrapper', - isRequired: true, - }, - type: { - type: 'MoveType', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveStructGenericTypeParam.ts b/m1/JavaScript-client/src/generated/schemas/$MoveStructGenericTypeParam.ts deleted file mode 100644 index b4a60c99c..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveStructGenericTypeParam.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveStructGenericTypeParam = { - description: `Move generic type param`, - properties: { - constraints: { - type: 'array', - contains: { - type: 'MoveAbility', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveStructTag.ts b/m1/JavaScript-client/src/generated/schemas/$MoveStructTag.ts deleted file mode 100644 index 0bd557c6c..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveStructTag.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveStructTag = { - type: 'string', - description: `String representation of a MoveStructTag (on-chain Move struct type). This exists so you - can specify MoveStructTags as path / query parameters, e.g. for get_events_by_event_handle. - - It is a combination of: - 1. \`move_module_address\`, \`module_name\` and \`struct_name\`, all joined by \`::\` - 2. \`struct generic type parameters\` joined by \`, \` - - Examples: - * \`0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>\` - * \`0x1::account::Account\` - - Note: - 1. Empty chars should be ignored when comparing 2 struct tag ids. - 2. When used in an URL path, should be encoded by url-encoding (AKA percent-encoding). - - See [doc](https://aptos.dev/concepts/accounts) for more details. - `, - pattern: '^0x[0-9a-zA-Z:_<>]+$', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveStructValue.ts b/m1/JavaScript-client/src/generated/schemas/$MoveStructValue.ts deleted file mode 100644 index bff113d62..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveStructValue.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveStructValue = { - description: `This is a JSON representation of some data within an account resource. More specifically, - it is a map of strings to arbitrary JSON values / objects, where the keys are top level - fields within the given resource. - - To clarify, you might query for 0x1::account::Account and see the example data. - - Move \`bool\` type value is serialized into \`boolean\`. - - Move \`u8\`, \`u16\` and \`u32\` type value is serialized into \`integer\`. - - Move \`u64\`, \`u128\` and \`u256\` type value is serialized into \`string\`. - - Move \`address\` type value (32 byte Aptos account address) is serialized into a HexEncodedBytes string. - For example: - - \`0x1\` - - \`0x1668f6be25668c1a17cd8caf6b8d2f25\` - - Move \`vector\` type value is serialized into \`array\`, except \`vector\` which is serialized into a - HexEncodedBytes string with \`0x\` prefix. - For example: - - \`vector{255, 255}\` => \`["255", "255"]\` - - \`vector{255, 255}\` => \`0xffff\` - - Move \`struct\` type value is serialized into \`object\` that looks like this (except some Move stdlib types, see the following section): - \`\`\`json - { - field1_name: field1_value, - field2_name: field2_value, - ...... - } - \`\`\` - - For example: - \`{ "created": "0xa550c18", "role_id": "0" }\` - - **Special serialization for Move stdlib types**: - - [0x1::string::String](https://github.com/aptos-labs/aptos-core/blob/main/language/move-stdlib/docs/ascii.md) - is serialized into \`string\`. For example, struct value \`0x1::string::String{bytes: b"Hello World!"}\` - is serialized as \`"Hello World!"\` in JSON. - `, - properties: { - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveType.ts b/m1/JavaScript-client/src/generated/schemas/$MoveType.ts deleted file mode 100644 index 56f4279bd..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveType.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveType = { - type: 'string', - description: `String representation of an on-chain Move type tag that is exposed in transaction payload. - Values: - - bool - - u8 - - u16 - - u32 - - u64 - - u128 - - u256 - - address - - signer - - vector: \`vector<{non-reference MoveTypeId}>\` - - struct: \`{address}::{module_name}::{struct_name}::<{generic types}>\` - - Vector type value examples: - - \`vector\` - - \`vector>\` - - \`vector<0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>>\` - - Struct type value examples: - - \`0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin> - - \`0x1::account::Account\` - - Note: - 1. Empty chars should be ignored when comparing 2 struct tag ids. - 2. When used in an URL path, should be encoded by url-encoding (AKA percent-encoding). - `, - pattern: '^(bool|u8|u64|u128|address|signer|vector<.+>|0x[0-9a-zA-Z:_<, >]+)$', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MoveValue.ts b/m1/JavaScript-client/src/generated/schemas/$MoveValue.ts deleted file mode 100644 index c4ac27bf7..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MoveValue.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MoveValue = { - type: 'any-of', - description: `An enum of the possible Move value types`, - contains: [{ - type: 'number', - format: 'uint8', - }, { - type: 'number', - format: 'uint16', - }, { - type: 'number', - format: 'uint32', - }, { - type: 'U64', - }, { - type: 'U128', - }, { - type: 'U256', - }, { - type: 'boolean', - }, { - type: 'Address', - }, { - type: 'array', - contains: { - type: 'MoveValue', - }, - }, { - type: 'HexEncodedBytes', - }, { - type: 'MoveStructValue', - }, { - type: 'string', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MultiAgentSignature.ts b/m1/JavaScript-client/src/generated/schemas/$MultiAgentSignature.ts deleted file mode 100644 index 3c1cff182..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MultiAgentSignature.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MultiAgentSignature = { - description: `Multi agent signature for multi agent transactions - - This allows you to have transactions across multiple accounts`, - properties: { - sender: { - type: 'AccountSignature', - isRequired: true, - }, - secondary_signer_addresses: { - type: 'array', - contains: { - type: 'Address', - }, - isRequired: true, - }, - secondary_signers: { - type: 'array', - contains: { - type: 'AccountSignature', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MultiEd25519Signature.ts b/m1/JavaScript-client/src/generated/schemas/$MultiEd25519Signature.ts deleted file mode 100644 index 1af586f67..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MultiEd25519Signature.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MultiEd25519Signature = { - description: `A Ed25519 multi-sig signature - - This allows k-of-n signing for a transaction`, - properties: { - public_keys: { - type: 'array', - contains: { - type: 'HexEncodedBytes', - }, - isRequired: true, - }, - signatures: { - type: 'array', - contains: { - type: 'HexEncodedBytes', - }, - isRequired: true, - }, - threshold: { - type: 'number', - description: `The number of signatures required for a successful transaction`, - isRequired: true, - format: 'uint8', - }, - bitmap: { - type: 'HexEncodedBytes', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MultisigPayload.ts b/m1/JavaScript-client/src/generated/schemas/$MultisigPayload.ts deleted file mode 100644 index 3db2ec250..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MultisigPayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MultisigPayload = { - description: `A multisig transaction that allows an owner of a multisig account to execute a pre-approved - transaction as the multisig account.`, - properties: { - multisig_address: { - type: 'Address', - isRequired: true, - }, - transaction_payload: { - type: 'MultisigTransactionPayload', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$MultisigTransactionPayload.ts b/m1/JavaScript-client/src/generated/schemas/$MultisigTransactionPayload.ts deleted file mode 100644 index d1f7dec50..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$MultisigTransactionPayload.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $MultisigTransactionPayload = { - type: 'any-of', - contains: [{ - type: 'EntryFunctionPayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$PendingTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$PendingTransaction.ts deleted file mode 100644 index cffa02859..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$PendingTransaction.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $PendingTransaction = { - description: `A transaction waiting in mempool`, - properties: { - hash: { - type: 'HashValue', - isRequired: true, - }, - sender: { - type: 'Address', - isRequired: true, - }, - sequence_number: { - type: 'U64', - isRequired: true, - }, - max_gas_amount: { - type: 'U64', - isRequired: true, - }, - gas_unit_price: { - type: 'U64', - isRequired: true, - }, - expiration_timestamp_secs: { - type: 'U64', - isRequired: true, - }, - payload: { - type: 'TransactionPayload', - isRequired: true, - }, - signature: { - type: 'TransactionSignature', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$RawTableItemRequest.ts b/m1/JavaScript-client/src/generated/schemas/$RawTableItemRequest.ts deleted file mode 100644 index b8fc9f023..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$RawTableItemRequest.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $RawTableItemRequest = { - description: `Table Item request for the GetTableItemRaw API`, - properties: { - key: { - type: 'HexEncodedBytes', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$RoleType.ts b/m1/JavaScript-client/src/generated/schemas/$RoleType.ts deleted file mode 100644 index 2f64bda0b..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$RoleType.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $RoleType = { - type: 'Enum', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$ScriptPayload.ts b/m1/JavaScript-client/src/generated/schemas/$ScriptPayload.ts deleted file mode 100644 index cf52931c6..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$ScriptPayload.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $ScriptPayload = { - description: `Payload which runs a script that can run multiple functions`, - properties: { - code: { - type: 'MoveScriptBytecode', - isRequired: true, - }, - type_arguments: { - type: 'array', - contains: { - type: 'MoveType', - }, - isRequired: true, - }, - arguments: { - type: 'array', - contains: { - properties: { - }, - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$ScriptWriteSet.ts b/m1/JavaScript-client/src/generated/schemas/$ScriptWriteSet.ts deleted file mode 100644 index 81effeee1..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$ScriptWriteSet.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $ScriptWriteSet = { - properties: { - execute_as: { - type: 'Address', - isRequired: true, - }, - script: { - type: 'ScriptPayload', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$StateCheckpointTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$StateCheckpointTransaction.ts deleted file mode 100644 index 608c8980a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$StateCheckpointTransaction.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $StateCheckpointTransaction = { - description: `A state checkpoint transaction`, - properties: { - version: { - type: 'U64', - isRequired: true, - }, - hash: { - type: 'HashValue', - isRequired: true, - }, - state_change_hash: { - type: 'HashValue', - isRequired: true, - }, - event_root_hash: { - type: 'HashValue', - isRequired: true, - }, - state_checkpoint_hash: { - type: 'HashValue', - }, - gas_used: { - type: 'U64', - isRequired: true, - }, - success: { - type: 'boolean', - description: `Whether the transaction was successful`, - isRequired: true, - }, - vm_status: { - type: 'string', - description: `The VM status of the transaction, can tell useful information in a failure`, - isRequired: true, - }, - accumulator_root_hash: { - type: 'HashValue', - isRequired: true, - }, - changes: { - type: 'array', - contains: { - type: 'WriteSetChange', - }, - isRequired: true, - }, - timestamp: { - type: 'U64', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$StateKeyWrapper.ts b/m1/JavaScript-client/src/generated/schemas/$StateKeyWrapper.ts deleted file mode 100644 index e4b0eb8ec..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$StateKeyWrapper.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $StateKeyWrapper = { - type: 'string', - description: `Representation of a StateKey as a hex string. This is used for cursor based pagination. - `, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$SubmitTransactionRequest.ts b/m1/JavaScript-client/src/generated/schemas/$SubmitTransactionRequest.ts deleted file mode 100644 index 4740d4a7d..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$SubmitTransactionRequest.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $SubmitTransactionRequest = { - description: `A request to submit a transaction - - This requires a transaction and a signature of it`, - properties: { - sender: { - type: 'Address', - isRequired: true, - }, - sequence_number: { - type: 'U64', - isRequired: true, - }, - max_gas_amount: { - type: 'U64', - isRequired: true, - }, - gas_unit_price: { - type: 'U64', - isRequired: true, - }, - expiration_timestamp_secs: { - type: 'U64', - isRequired: true, - }, - payload: { - type: 'TransactionPayload', - isRequired: true, - }, - signature: { - type: 'TransactionSignature', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TableItemRequest.ts b/m1/JavaScript-client/src/generated/schemas/$TableItemRequest.ts deleted file mode 100644 index 6cd81ea5c..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TableItemRequest.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TableItemRequest = { - description: `Table Item request for the GetTableItem API`, - properties: { - key_type: { - type: 'MoveType', - isRequired: true, - }, - value_type: { - type: 'MoveType', - isRequired: true, - }, - key: { - description: `The value of the table item's key`, - properties: { - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Transaction.ts b/m1/JavaScript-client/src/generated/schemas/$Transaction.ts deleted file mode 100644 index 0aa1e257d..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Transaction.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Transaction = { - type: 'one-of', - description: `Enum of the different types of transactions in Aptos`, - contains: [{ - type: 'Transaction_PendingTransaction', - }, { - type: 'Transaction_UserTransaction', - }, { - type: 'Transaction_GenesisTransaction', - }, { - type: 'Transaction_BlockMetadataTransaction', - }, { - type: 'Transaction_StateCheckpointTransaction', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionPayload.ts deleted file mode 100644 index 9f8d72da2..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionPayload = { - type: 'one-of', - description: `An enum of the possible transaction payloads`, - contains: [{ - type: 'TransactionPayload_EntryFunctionPayload', - }, { - type: 'TransactionPayload_ScriptPayload', - }, { - type: 'TransactionPayload_ModuleBundlePayload', - }, { - type: 'TransactionPayload_MultisigPayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_EntryFunctionPayload.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_EntryFunctionPayload.ts deleted file mode 100644 index e7ea8d6c8..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_EntryFunctionPayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionPayload_EntryFunctionPayload = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'EntryFunctionPayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_ModuleBundlePayload.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_ModuleBundlePayload.ts deleted file mode 100644 index 4ee6f0add..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_ModuleBundlePayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionPayload_ModuleBundlePayload = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'ModuleBundlePayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_MultisigPayload.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_MultisigPayload.ts deleted file mode 100644 index 18ee4df67..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_MultisigPayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionPayload_MultisigPayload = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'MultisigPayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_ScriptPayload.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_ScriptPayload.ts deleted file mode 100644 index d15b4c865..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionPayload_ScriptPayload.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionPayload_ScriptPayload = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'ScriptPayload', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionSignature.ts deleted file mode 100644 index 08df557f2..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionSignature = { - type: 'one-of', - description: `An enum representing the different transaction signatures available`, - contains: [{ - type: 'TransactionSignature_Ed25519Signature', - }, { - type: 'TransactionSignature_MultiEd25519Signature', - }, { - type: 'TransactionSignature_MultiAgentSignature', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_Ed25519Signature.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_Ed25519Signature.ts deleted file mode 100644 index 2f754f0cb..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_Ed25519Signature.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionSignature_Ed25519Signature = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'Ed25519Signature', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_MultiAgentSignature.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_MultiAgentSignature.ts deleted file mode 100644 index c6c6ce5fd..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_MultiAgentSignature.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionSignature_MultiAgentSignature = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'MultiAgentSignature', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_MultiEd25519Signature.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_MultiEd25519Signature.ts deleted file mode 100644 index e6ffaf205..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionSignature_MultiEd25519Signature.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionSignature_MultiEd25519Signature = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'MultiEd25519Signature', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Transaction_BlockMetadataTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$Transaction_BlockMetadataTransaction.ts deleted file mode 100644 index 55aa7c461..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Transaction_BlockMetadataTransaction.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Transaction_BlockMetadataTransaction = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'BlockMetadataTransaction', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Transaction_GenesisTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$Transaction_GenesisTransaction.ts deleted file mode 100644 index adb40078a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Transaction_GenesisTransaction.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Transaction_GenesisTransaction = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'GenesisTransaction', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Transaction_PendingTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$Transaction_PendingTransaction.ts deleted file mode 100644 index 8663a50be..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Transaction_PendingTransaction.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Transaction_PendingTransaction = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'PendingTransaction', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Transaction_StateCheckpointTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$Transaction_StateCheckpointTransaction.ts deleted file mode 100644 index 19435016f..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Transaction_StateCheckpointTransaction.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Transaction_StateCheckpointTransaction = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'StateCheckpointTransaction', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$Transaction_UserTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$Transaction_UserTransaction.ts deleted file mode 100644 index b0bbf989c..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$Transaction_UserTransaction.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $Transaction_UserTransaction = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'UserTransaction', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionsBatchSingleSubmissionFailure.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionsBatchSingleSubmissionFailure.ts deleted file mode 100644 index 2f6465cc3..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionsBatchSingleSubmissionFailure.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionsBatchSingleSubmissionFailure = { - description: `Information telling which batch submission transactions failed`, - properties: { - error: { - type: 'AptosError', - isRequired: true, - }, - transaction_index: { - type: 'number', - description: `The index of which transaction failed, same as submission order`, - isRequired: true, - format: 'uint64', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$TransactionsBatchSubmissionResult.ts b/m1/JavaScript-client/src/generated/schemas/$TransactionsBatchSubmissionResult.ts deleted file mode 100644 index 3e04e03ca..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$TransactionsBatchSubmissionResult.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $TransactionsBatchSubmissionResult = { - description: `Batch transaction submission result - - Tells which transactions failed`, - properties: { - transaction_failures: { - type: 'array', - contains: { - type: 'TransactionsBatchSingleSubmissionFailure', - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$U128.ts b/m1/JavaScript-client/src/generated/schemas/$U128.ts deleted file mode 100644 index 645248548..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$U128.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $U128 = { - type: 'string', - description: `A string containing a 128-bit unsigned integer. - - We represent u128 values as a string to ensure compatibility with languages such - as JavaScript that do not parse u128s in JSON natively. - `, - format: 'uint128', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$U256.ts b/m1/JavaScript-client/src/generated/schemas/$U256.ts deleted file mode 100644 index 20e7c0e14..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$U256.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $U256 = { - type: 'string', - description: `A string containing a 256-bit unsigned integer. - - We represent u256 values as a string to ensure compatibility with languages such - as JavaScript that do not parse u256s in JSON natively. - `, - format: 'uint256', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$U64.ts b/m1/JavaScript-client/src/generated/schemas/$U64.ts deleted file mode 100644 index c98a054b1..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$U64.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $U64 = { - type: 'string', - description: `A string containing a 64-bit unsigned integer. - - We represent u64 values as a string to ensure compatibility with languages such - as JavaScript that do not parse u64s in JSON natively. - `, - format: 'uint64', -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$UserTransaction.ts b/m1/JavaScript-client/src/generated/schemas/$UserTransaction.ts deleted file mode 100644 index 2ef0ed7ee..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$UserTransaction.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $UserTransaction = { - description: `A transaction submitted by a user to change the state of the blockchain`, - properties: { - version: { - type: 'U64', - isRequired: true, - }, - hash: { - type: 'HashValue', - isRequired: true, - }, - state_change_hash: { - type: 'HashValue', - isRequired: true, - }, - event_root_hash: { - type: 'HashValue', - isRequired: true, - }, - state_checkpoint_hash: { - type: 'HashValue', - }, - gas_used: { - type: 'U64', - isRequired: true, - }, - success: { - type: 'boolean', - description: `Whether the transaction was successful`, - isRequired: true, - }, - vm_status: { - type: 'string', - description: `The VM status of the transaction, can tell useful information in a failure`, - isRequired: true, - }, - accumulator_root_hash: { - type: 'HashValue', - isRequired: true, - }, - changes: { - type: 'array', - contains: { - type: 'WriteSetChange', - }, - isRequired: true, - }, - sender: { - type: 'Address', - isRequired: true, - }, - sequence_number: { - type: 'U64', - isRequired: true, - }, - max_gas_amount: { - type: 'U64', - isRequired: true, - }, - gas_unit_price: { - type: 'U64', - isRequired: true, - }, - expiration_timestamp_secs: { - type: 'U64', - isRequired: true, - }, - payload: { - type: 'TransactionPayload', - isRequired: true, - }, - signature: { - type: 'TransactionSignature', - }, - events: { - type: 'array', - contains: { - type: 'Event', - }, - isRequired: true, - }, - timestamp: { - type: 'U64', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$VersionedEvent.ts b/m1/JavaScript-client/src/generated/schemas/$VersionedEvent.ts deleted file mode 100644 index 7e935382a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$VersionedEvent.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $VersionedEvent = { - description: `An event from a transaction with a version`, - properties: { - version: { - type: 'U64', - isRequired: true, - }, - guid: { - type: 'EventGuid', - isRequired: true, - }, - sequence_number: { - type: 'U64', - isRequired: true, - }, - type: { - type: 'MoveType', - isRequired: true, - }, - data: { - description: `The JSON representation of the event`, - properties: { - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$ViewRequest.ts b/m1/JavaScript-client/src/generated/schemas/$ViewRequest.ts deleted file mode 100644 index 28994b8e4..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$ViewRequest.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $ViewRequest = { - description: `View request for the Move View Function API`, - properties: { - function: { - type: 'EntryFunctionId', - isRequired: true, - }, - type_arguments: { - type: 'array', - contains: { - type: 'MoveType', - }, - isRequired: true, - }, - arguments: { - type: 'array', - contains: { - properties: { - }, - }, - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteModule.ts b/m1/JavaScript-client/src/generated/schemas/$WriteModule.ts deleted file mode 100644 index cd41e48e8..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteModule.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteModule = { - description: `Write a new module or update an existing one`, - properties: { - address: { - type: 'Address', - isRequired: true, - }, - state_key_hash: { - type: 'string', - description: `State key hash`, - isRequired: true, - }, - data: { - type: 'MoveModuleBytecode', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteResource.ts b/m1/JavaScript-client/src/generated/schemas/$WriteResource.ts deleted file mode 100644 index aff2055a8..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteResource.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteResource = { - description: `Write a resource or update an existing one`, - properties: { - address: { - type: 'Address', - isRequired: true, - }, - state_key_hash: { - type: 'string', - description: `State key hash`, - isRequired: true, - }, - data: { - type: 'MoveResource', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSet.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSet.ts deleted file mode 100644 index a6a86944e..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSet.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSet = { - type: 'one-of', - description: `The associated writeset with a payload`, - contains: [{ - type: 'WriteSet_ScriptWriteSet', - }, { - type: 'WriteSet_DirectWriteSet', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetChange.ts deleted file mode 100644 index c6c2edb0a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetChange = { - type: 'one-of', - description: `A final state change of a transaction on a resource or module`, - contains: [{ - type: 'WriteSetChange_DeleteModule', - }, { - type: 'WriteSetChange_DeleteResource', - }, { - type: 'WriteSetChange_DeleteTableItem', - }, { - type: 'WriteSetChange_WriteModule', - }, { - type: 'WriteSetChange_WriteResource', - }, { - type: 'WriteSetChange_WriteTableItem', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteModule.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteModule.ts deleted file mode 100644 index 2ec713287..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteModule.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetChange_DeleteModule = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'DeleteModule', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteResource.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteResource.ts deleted file mode 100644 index 8346da07a..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteResource.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetChange_DeleteResource = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'DeleteResource', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteTableItem.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteTableItem.ts deleted file mode 100644 index ae905f573..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_DeleteTableItem.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetChange_DeleteTableItem = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'DeleteTableItem', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteModule.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteModule.ts deleted file mode 100644 index d0ec80fb5..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteModule.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetChange_WriteModule = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'WriteModule', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteResource.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteResource.ts deleted file mode 100644 index 9febd5b83..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteResource.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetChange_WriteResource = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'WriteResource', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteTableItem.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteTableItem.ts deleted file mode 100644 index eb8d77dee..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetChange_WriteTableItem.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetChange_WriteTableItem = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'WriteTableItem', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSetPayload.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSetPayload.ts deleted file mode 100644 index abe858d63..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSetPayload.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSetPayload = { - description: `A writeset payload, used only for genesis`, - properties: { - write_set: { - type: 'WriteSet', - isRequired: true, - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSet_DirectWriteSet.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSet_DirectWriteSet.ts deleted file mode 100644 index d9d893581..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSet_DirectWriteSet.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSet_DirectWriteSet = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'DirectWriteSet', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteSet_ScriptWriteSet.ts b/m1/JavaScript-client/src/generated/schemas/$WriteSet_ScriptWriteSet.ts deleted file mode 100644 index b3a3ebeee..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteSet_ScriptWriteSet.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteSet_ScriptWriteSet = { - type: 'all-of', - contains: [{ - properties: { - type: { - type: 'string', - isRequired: true, - }, - }, - }, { - type: 'ScriptWriteSet', - }], -} as const; diff --git a/m1/JavaScript-client/src/generated/schemas/$WriteTableItem.ts b/m1/JavaScript-client/src/generated/schemas/$WriteTableItem.ts deleted file mode 100644 index 1d1273fdc..000000000 --- a/m1/JavaScript-client/src/generated/schemas/$WriteTableItem.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -export const $WriteTableItem = { - description: `Change set to write a table item`, - properties: { - state_key_hash: { - type: 'string', - isRequired: true, - }, - handle: { - type: 'HexEncodedBytes', - isRequired: true, - }, - key: { - type: 'HexEncodedBytes', - isRequired: true, - }, - value: { - type: 'HexEncodedBytes', - isRequired: true, - }, - data: { - type: 'DecodedTableData', - }, - }, -} as const; diff --git a/m1/JavaScript-client/src/generated/services/AccountsService.ts b/m1/JavaScript-client/src/generated/services/AccountsService.ts deleted file mode 100644 index 08f87cba6..000000000 --- a/m1/JavaScript-client/src/generated/services/AccountsService.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { AccountData } from '../models/AccountData'; -import type { Address } from '../models/Address'; -import type { IdentifierWrapper } from '../models/IdentifierWrapper'; -import type { MoveModuleBytecode } from '../models/MoveModuleBytecode'; -import type { MoveResource } from '../models/MoveResource'; -import type { MoveStructTag } from '../models/MoveStructTag'; -import type { StateKeyWrapper } from '../models/StateKeyWrapper'; -import type { U64 } from '../models/U64'; - -import type { CancelablePromise } from '../core/CancelablePromise'; -import type { BaseHttpRequest } from '../core/BaseHttpRequest'; - -export class AccountsService { - - constructor(public readonly httpRequest: BaseHttpRequest) {} - - /** - * Get account - * Return the authentication key and the sequence number for an account - * address. Optionally, a ledger version can be specified. If the ledger - * version is not specified in the request, the latest ledger version is used. - * @param address Address of account with or without a `0x` prefix - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @returns AccountData - * @throws ApiError - */ - public getAccount( - address: Address, - ledgerVersion?: U64, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}', - path: { - 'address': address, - }, - query: { - 'ledger_version': ledgerVersion, - }, - }); - } - - /** - * Get account resources - * Retrieves all account resources for a given account and a specific ledger version. If the - * ledger version is not specified in the request, the latest ledger version is used. - * - * The Aptos nodes prune account state history, via a configurable time window. - * If the requested ledger version has been pruned, the server responds with a 410. - * @param address Address of account with or without a `0x` prefix - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @param start Cursor specifying where to start for pagination - * - * This cursor cannot be derived manually client-side. Instead, you must - * call this endpoint once without this query parameter specified, and - * then use the cursor returned in the X-Aptos-Cursor header in the - * response. - * @param limit Max number of account resources to retrieve - * - * If not provided, defaults to default page size. - * @returns MoveResource - * @throws ApiError - */ - public getAccountResources( - address: Address, - ledgerVersion?: U64, - start?: StateKeyWrapper, - limit?: number, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}/resources', - path: { - 'address': address, - }, - query: { - 'ledger_version': ledgerVersion, - 'start': start, - 'limit': limit, - }, - }); - } - - /** - * Get account modules - * Retrieves all account modules' bytecode for a given account at a specific ledger version. - * If the ledger version is not specified in the request, the latest ledger version is used. - * - * The Aptos nodes prune account state history, via a configurable time window. - * If the requested ledger version has been pruned, the server responds with a 410. - * @param address Address of account with or without a `0x` prefix - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @param start Cursor specifying where to start for pagination - * - * This cursor cannot be derived manually client-side. Instead, you must - * call this endpoint once without this query parameter specified, and - * then use the cursor returned in the X-Aptos-Cursor header in the - * response. - * @param limit Max number of account modules to retrieve - * - * If not provided, defaults to default page size. - * @returns MoveModuleBytecode - * @throws ApiError - */ - public getAccountModules( - address: Address, - ledgerVersion?: U64, - start?: StateKeyWrapper, - limit?: number, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}/modules', - path: { - 'address': address, - }, - query: { - 'ledger_version': ledgerVersion, - 'start': start, - 'limit': limit, - }, - }); - } - - /** - * Get account resource - * Retrieves an individual resource from a given account and at a specific ledger version. If the - * ledger version is not specified in the request, the latest ledger version is used. - * - * The Aptos nodes prune account state history, via a configurable time window. - * If the requested ledger version has been pruned, the server responds with a 410. - * @param address Address of account with or without a `0x` prefix - * @param resourceType Name of struct to retrieve e.g. `0x1::account::Account` - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @returns MoveResource - * @throws ApiError - */ - public getAccountResource( - address: Address, - resourceType: MoveStructTag, - ledgerVersion?: U64, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}/resource/{resource_type}', - path: { - 'address': address, - 'resource_type': resourceType, - }, - query: { - 'ledger_version': ledgerVersion, - }, - }); - } - - /** - * Get account module - * Retrieves an individual module from a given account and at a specific ledger version. If the - * ledger version is not specified in the request, the latest ledger version is used. - * - * The Aptos nodes prune account state history, via a configurable time window. - * If the requested ledger version has been pruned, the server responds with a 410. - * @param address Address of account with or without a `0x` prefix - * @param moduleName Name of module to retrieve e.g. `coin` - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @returns MoveModuleBytecode - * @throws ApiError - */ - public getAccountModule( - address: Address, - moduleName: IdentifierWrapper, - ledgerVersion?: U64, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}/module/{module_name}', - path: { - 'address': address, - 'module_name': moduleName, - }, - query: { - 'ledger_version': ledgerVersion, - }, - }); - } - -} diff --git a/m1/JavaScript-client/src/generated/services/BlocksService.ts b/m1/JavaScript-client/src/generated/services/BlocksService.ts deleted file mode 100644 index b9dbe17b5..000000000 --- a/m1/JavaScript-client/src/generated/services/BlocksService.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { Block } from '../models/Block'; - -import type { CancelablePromise } from '../core/CancelablePromise'; -import type { BaseHttpRequest } from '../core/BaseHttpRequest'; - -export class BlocksService { - - constructor(public readonly httpRequest: BaseHttpRequest) {} - - /** - * Get blocks by height - * This endpoint allows you to get the transactions in a block - * and the corresponding block information. - * - * Transactions are limited by max default transactions size. If not all transactions - * are present, the user will need to query for the rest of the transactions via the - * get transactions API. - * - * If the block is pruned, it will return a 410 - * @param blockHeight Block height to lookup. Starts at 0 - * @param withTransactions If set to true, include all transactions in the block - * - * If not provided, no transactions will be retrieved - * @returns Block - * @throws ApiError - */ - public getBlockByHeight( - blockHeight: number, - withTransactions?: boolean, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/blocks/by_height/{block_height}', - path: { - 'block_height': blockHeight, - }, - query: { - 'with_transactions': withTransactions, - }, - }); - } - - /** - * Get blocks by version - * This endpoint allows you to get the transactions in a block - * and the corresponding block information given a version in the block. - * - * Transactions are limited by max default transactions size. If not all transactions - * are present, the user will need to query for the rest of the transactions via the - * get transactions API. - * - * If the block has been pruned, it will return a 410 - * @param version Ledger version to lookup block information for. - * @param withTransactions If set to true, include all transactions in the block - * - * If not provided, no transactions will be retrieved - * @returns Block - * @throws ApiError - */ - public getBlockByVersion( - version: number, - withTransactions?: boolean, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/blocks/by_version/{version}', - path: { - 'version': version, - }, - query: { - 'with_transactions': withTransactions, - }, - }); - } - -} diff --git a/m1/JavaScript-client/src/generated/services/EventsService.ts b/m1/JavaScript-client/src/generated/services/EventsService.ts deleted file mode 100644 index 9396944b1..000000000 --- a/m1/JavaScript-client/src/generated/services/EventsService.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { Address } from '../models/Address'; -import type { IdentifierWrapper } from '../models/IdentifierWrapper'; -import type { MoveStructTag } from '../models/MoveStructTag'; -import type { U64 } from '../models/U64'; -import type { VersionedEvent } from '../models/VersionedEvent'; - -import type { CancelablePromise } from '../core/CancelablePromise'; -import type { BaseHttpRequest } from '../core/BaseHttpRequest'; - -export class EventsService { - - constructor(public readonly httpRequest: BaseHttpRequest) {} - - /** - * Get events by creation number - * Event types are globally identifiable by an account `address` and - * monotonically increasing `creation_number`, one per event type emitted - * to the given account. This API returns events corresponding to that - * that event type. - * @param address Hex-encoded 32 byte Aptos account, with or without a `0x` prefix, for - * which events are queried. This refers to the account that events were - * emitted to, not the account hosting the move module that emits that - * event type. - * @param creationNumber Creation number corresponding to the event stream originating - * from the given account. - * @param start Starting sequence number of events. - * - * If unspecified, by default will retrieve the most recent events - * @param limit Max number of events to retrieve. - * - * If unspecified, defaults to default page size - * @returns VersionedEvent - * @throws ApiError - */ - public getEventsByCreationNumber( - address: Address, - creationNumber: U64, - start?: U64, - limit?: number, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}/events/{creation_number}', - path: { - 'address': address, - 'creation_number': creationNumber, - }, - query: { - 'start': start, - 'limit': limit, - }, - }); - } - - /** - * Get events by event handle - * This API uses the given account `address`, `eventHandle`, and `fieldName` - * to build a key that can globally identify an event types. It then uses this - * key to return events emitted to the given account matching that event type. - * @param address Hex-encoded 32 byte Aptos account, with or without a `0x` prefix, for - * which events are queried. This refers to the account that events were - * emitted to, not the account hosting the move module that emits that - * event type. - * @param eventHandle Name of struct to lookup event handle e.g. `0x1::account::Account` - * @param fieldName Name of field to lookup event handle e.g. `withdraw_events` - * @param start Starting sequence number of events. - * - * If unspecified, by default will retrieve the most recent - * @param limit Max number of events to retrieve. - * - * If unspecified, defaults to default page size - * @returns VersionedEvent - * @throws ApiError - */ - public getEventsByEventHandle( - address: Address, - eventHandle: MoveStructTag, - fieldName: IdentifierWrapper, - start?: U64, - limit?: number, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}/events/{event_handle}/{field_name}', - path: { - 'address': address, - 'event_handle': eventHandle, - 'field_name': fieldName, - }, - query: { - 'start': start, - 'limit': limit, - }, - }); - } - -} diff --git a/m1/JavaScript-client/src/generated/services/GeneralService.ts b/m1/JavaScript-client/src/generated/services/GeneralService.ts deleted file mode 100644 index 3b06ef495..000000000 --- a/m1/JavaScript-client/src/generated/services/GeneralService.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { HealthCheckSuccess } from '../models/HealthCheckSuccess'; -import type { IndexResponse } from '../models/IndexResponse'; - -import type { CancelablePromise } from '../core/CancelablePromise'; -import type { BaseHttpRequest } from '../core/BaseHttpRequest'; - -export class GeneralService { - - constructor(public readonly httpRequest: BaseHttpRequest) {} - - /** - * Show OpenAPI explorer - * Provides a UI that you can use to explore the API. You can also - * retrieve the API directly at `/spec.yaml` and `/spec.json`. - * @returns string - * @throws ApiError - */ - public spec(): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/spec', - }); - } - - /** - * Check basic node health - * By default this endpoint just checks that it can get the latest ledger - * info and then returns 200. - * - * If the duration_secs param is provided, this endpoint will return a - * 200 if the following condition is true: - * - * `server_latest_ledger_info_timestamp >= server_current_time_timestamp - duration_secs` - * @param durationSecs Threshold in seconds that the server can be behind to be considered healthy - * - * If not provided, the healthcheck will always succeed - * @returns HealthCheckSuccess - * @throws ApiError - */ - public healthy( - durationSecs?: number, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/-/healthy', - query: { - 'duration_secs': durationSecs, - }, - }); - } - - /** - * Get ledger info - * Get the latest ledger information, including data such as chain ID, - * role type, ledger versions, epoch, etc. - * @returns IndexResponse - * @throws ApiError - */ - public getLedgerInfo(): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/', - }); - } - -} diff --git a/m1/JavaScript-client/src/generated/services/TablesService.ts b/m1/JavaScript-client/src/generated/services/TablesService.ts deleted file mode 100644 index ce909f85e..000000000 --- a/m1/JavaScript-client/src/generated/services/TablesService.ts +++ /dev/null @@ -1,93 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { Address } from '../models/Address'; -import type { MoveValue } from '../models/MoveValue'; -import type { RawTableItemRequest } from '../models/RawTableItemRequest'; -import type { TableItemRequest } from '../models/TableItemRequest'; -import type { U64 } from '../models/U64'; - -import type { CancelablePromise } from '../core/CancelablePromise'; -import type { BaseHttpRequest } from '../core/BaseHttpRequest'; - -export class TablesService { - - constructor(public readonly httpRequest: BaseHttpRequest) {} - - /** - * Get table item - * Get a table item at a specific ledger version from the table identified by {table_handle} - * in the path and the "key" (TableItemRequest) provided in the request body. - * - * This is a POST endpoint because the "key" for requesting a specific - * table item (TableItemRequest) could be quite complex, as each of its - * fields could themselves be composed of other structs. This makes it - * impractical to express using query params, meaning GET isn't an option. - * - * The Aptos nodes prune account state history, via a configurable time window. - * If the requested ledger version has been pruned, the server responds with a 410. - * @param tableHandle Table handle hex encoded 32-byte string - * @param requestBody - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @returns MoveValue - * @throws ApiError - */ - public getTableItem( - tableHandle: Address, - requestBody: TableItemRequest, - ledgerVersion?: U64, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'POST', - url: '/tables/{table_handle}/item', - path: { - 'table_handle': tableHandle, - }, - query: { - 'ledger_version': ledgerVersion, - }, - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * Get raw table item - * Get a table item at a specific ledger version from the table identified by {table_handle} - * in the path and the "key" (RawTableItemRequest) provided in the request body. - * - * The `get_raw_table_item` requires only a serialized key comparing to the full move type information - * comparing to the `get_table_item` api, and can only return the query in the bcs format. - * - * The Aptos nodes prune account state history, via a configurable time window. - * If the requested ledger version has been pruned, the server responds with a 410. - * @param tableHandle Table handle hex encoded 32-byte string - * @param requestBody - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @returns MoveValue - * @throws ApiError - */ - public getRawTableItem( - tableHandle: Address, - requestBody: RawTableItemRequest, - ledgerVersion?: U64, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'POST', - url: '/tables/{table_handle}/raw_item', - path: { - 'table_handle': tableHandle, - }, - query: { - 'ledger_version': ledgerVersion, - }, - body: requestBody, - mediaType: 'application/json', - }); - } - -} diff --git a/m1/JavaScript-client/src/generated/services/TransactionsService.ts b/m1/JavaScript-client/src/generated/services/TransactionsService.ts deleted file mode 100644 index 4f9ea4b2a..000000000 --- a/m1/JavaScript-client/src/generated/services/TransactionsService.ts +++ /dev/null @@ -1,302 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { Address } from '../models/Address'; -import type { EncodeSubmissionRequest } from '../models/EncodeSubmissionRequest'; -import type { GasEstimation } from '../models/GasEstimation'; -import type { HashValue } from '../models/HashValue'; -import type { HexEncodedBytes } from '../models/HexEncodedBytes'; -import type { PendingTransaction } from '../models/PendingTransaction'; -import type { SubmitTransactionRequest } from '../models/SubmitTransactionRequest'; -import type { Transaction } from '../models/Transaction'; -import type { TransactionsBatchSubmissionResult } from '../models/TransactionsBatchSubmissionResult'; -import type { U64 } from '../models/U64'; -import type { UserTransaction } from '../models/UserTransaction'; - -import type { CancelablePromise } from '../core/CancelablePromise'; -import type { BaseHttpRequest } from '../core/BaseHttpRequest'; - -export class TransactionsService { - - constructor(public readonly httpRequest: BaseHttpRequest) {} - - /** - * Get transactions - * Retrieve on-chain committed transactions. The page size and start ledger version - * can be provided to get a specific sequence of transactions. - * - * If the version has been pruned, then a 410 will be returned. - * - * To retrieve a pending transaction, use /transactions/by_hash. - * @param start Ledger version to start list of transactions - * - * If not provided, defaults to showing the latest transactions - * @param limit Max number of transactions to retrieve. - * - * If not provided, defaults to default page size - * @returns Transaction - * @throws ApiError - */ - public getTransactions( - start?: U64, - limit?: number, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'GET', - url: '/transactions', - query: { - 'start': start, - 'limit': limit, - }, - }); - } - - /** - * Submit transaction - * This endpoint accepts transaction submissions in two formats. - * - * To submit a transaction as JSON, you must submit a SubmitTransactionRequest. - * To build this request, do the following: - * - * 1. Encode the transaction as BCS. If you are using a language that has - * native BCS support, make sure of that library. If not, you may take - * advantage of /transactions/encode_submission. When using this - * endpoint, make sure you trust the node you're talking to, as it is - * possible they could manipulate your request. - * 2. Sign the encoded transaction and use it to create a TransactionSignature. - * 3. Submit the request. Make sure to use the "application/json" Content-Type. - * - * To submit a transaction as BCS, you must submit a SignedTransaction - * encoded as BCS. See SignedTransaction in types/src/transaction/mod.rs. - * Make sure to use the `application/x.aptos.signed_transaction+bcs` Content-Type. - * @param requestBody - * @returns PendingTransaction - * @throws ApiError - */ - public submitTransaction( - requestBody: SubmitTransactionRequest, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'POST', - url: '/transactions', - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * Get transaction by hash - * Look up a transaction by its hash. This is the same hash that is returned - * by the API when submitting a transaction (see PendingTransaction). - * - * When given a transaction hash, the server first looks for the transaction - * in storage (on-chain, committed). If no on-chain transaction is found, it - * looks the transaction up by hash in the mempool (pending, not yet committed). - * - * To create a transaction hash by yourself, do the following: - * 1. Hash message bytes: "RawTransaction" bytes + BCS bytes of [Transaction](https://aptos-labs.github.io/aptos-core/aptos_types/transaction/enum.Transaction.html). - * 2. Apply hash algorithm `SHA3-256` to the hash message bytes. - * 3. Hex-encode the hash bytes with `0x` prefix. - * @param txnHash Hash of transaction to retrieve - * @returns Transaction - * @throws ApiError - */ - public getTransactionByHash( - txnHash: HashValue, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/transactions/by_hash/{txn_hash}', - path: { - 'txn_hash': txnHash, - }, - }); - } - - /** - * Get transaction by version - * Retrieves a transaction by a given version. If the version has been - * pruned, a 410 will be returned. - * @param txnVersion Version of transaction to retrieve - * @returns Transaction - * @throws ApiError - */ - public getTransactionByVersion( - txnVersion: U64, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/transactions/by_version/{txn_version}', - path: { - 'txn_version': txnVersion, - }, - }); - } - - /** - * Get account transactions - * Retrieves on-chain committed transactions from an account. If the start - * version is too far in the past, a 410 will be returned. - * - * If no start version is given, it will start at version 0. - * - * To retrieve a pending transaction, use /transactions/by_hash. - * @param address Address of account with or without a `0x` prefix - * @param start Account sequence number to start list of transactions - * - * If not provided, defaults to showing the latest transactions - * @param limit Max number of transactions to retrieve. - * - * If not provided, defaults to default page size - * @returns Transaction - * @throws ApiError - */ - public getAccountTransactions( - address: Address, - start?: U64, - limit?: number, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'GET', - url: '/accounts/{address}/transactions', - path: { - 'address': address, - }, - query: { - 'start': start, - 'limit': limit, - }, - }); - } - - /** - * Submit batch transactions - * This allows you to submit multiple transactions. The response has three outcomes: - * - * 1. All transactions succeed, and it will return a 202 - * 2. Some transactions succeed, and it will return the failed transactions and a 206 - * 3. No transactions succeed, and it will also return the failed transactions and a 206 - * - * To submit a transaction as JSON, you must submit a SubmitTransactionRequest. - * To build this request, do the following: - * - * 1. Encode the transaction as BCS. If you are using a language that has - * native BCS support, make sure to use that library. If not, you may take - * advantage of /transactions/encode_submission. When using this - * endpoint, make sure you trust the node you're talking to, as it is - * possible they could manipulate your request. - * 2. Sign the encoded transaction and use it to create a TransactionSignature. - * 3. Submit the request. Make sure to use the "application/json" Content-Type. - * - * To submit a transaction as BCS, you must submit a SignedTransaction - * encoded as BCS. See SignedTransaction in types/src/transaction/mod.rs. - * Make sure to use the `application/x.aptos.signed_transaction+bcs` Content-Type. - * @param requestBody - * @returns TransactionsBatchSubmissionResult - * @throws ApiError - */ - public submitBatchTransactions( - requestBody: Array, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'POST', - url: '/transactions/batch', - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * Simulate transaction - * The output of the transaction will have the exact transaction outputs and events that running - * an actual signed transaction would have. However, it will not have the associated state - * hashes, as they are not updated in storage. This can be used to estimate the maximum gas - * units for a submitted transaction. - * - * To use this, you must: - * - Create a SignedTransaction with a zero-padded signature. - * - Submit a SubmitTransactionRequest containing a UserTransactionRequest containing that signature. - * - * To use this endpoint with BCS, you must submit a SignedTransaction - * encoded as BCS. See SignedTransaction in types/src/transaction/mod.rs. - * @param requestBody - * @param estimateMaxGasAmount If set to true, the max gas value in the transaction will be ignored - * and the maximum possible gas will be used - * @param estimateGasUnitPrice If set to true, the gas unit price in the transaction will be ignored - * and the estimated value will be used - * @param estimatePrioritizedGasUnitPrice If set to true, the transaction will use a higher price than the original - * estimate. - * @returns UserTransaction - * @throws ApiError - */ - public simulateTransaction( - requestBody: SubmitTransactionRequest, - estimateMaxGasAmount?: boolean, - estimateGasUnitPrice?: boolean, - estimatePrioritizedGasUnitPrice?: boolean, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'POST', - url: '/transactions/simulate', - query: { - 'estimate_max_gas_amount': estimateMaxGasAmount, - 'estimate_gas_unit_price': estimateGasUnitPrice, - 'estimate_prioritized_gas_unit_price': estimatePrioritizedGasUnitPrice, - }, - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * Encode submission - * This endpoint accepts an EncodeSubmissionRequest, which internally is a - * UserTransactionRequestInner (and optionally secondary signers) encoded - * as JSON, validates the request format, and then returns that request - * encoded in BCS. The client can then use this to create a transaction - * signature to be used in a SubmitTransactionRequest, which it then - * passes to the /transactions POST endpoint. - * - * To be clear, this endpoint makes it possible to submit transaction - * requests to the API from languages that do not have library support for - * BCS. If you are using an SDK that has BCS support, such as the official - * Rust, TypeScript, or Python SDKs, you do not need to use this endpoint. - * - * To sign a message using the response from this endpoint: - * - Decode the hex encoded string in the response to bytes. - * - Sign the bytes to create the signature. - * - Use that as the signature field in something like Ed25519Signature, which you then use to build a TransactionSignature. - * @param requestBody - * @returns HexEncodedBytes - * @throws ApiError - */ - public encodeSubmission( - requestBody: EncodeSubmissionRequest, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'POST', - url: '/transactions/encode_submission', - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * Estimate gas price - * Currently, the gas estimation is handled by taking the median of the last 100,000 transactions - * If a user wants to prioritize their transaction and is willing to pay, they can pay more - * than the gas price. If they're willing to wait longer, they can pay less. Note that the - * gas price moves with the fee market, and should only increase when demand outweighs supply. - * - * If there have been no transactions in the last 100,000 transactions, the price will be 1. - * @returns GasEstimation - * @throws ApiError - */ - public estimateGasPrice(): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/estimate_gas_price', - }); - } - -} diff --git a/m1/JavaScript-client/src/generated/services/ViewService.ts b/m1/JavaScript-client/src/generated/services/ViewService.ts deleted file mode 100644 index 8b4d40df7..000000000 --- a/m1/JavaScript-client/src/generated/services/ViewService.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { MoveValue } from '../models/MoveValue'; -import type { U64 } from '../models/U64'; -import type { ViewRequest } from '../models/ViewRequest'; - -import type { CancelablePromise } from '../core/CancelablePromise'; -import type { BaseHttpRequest } from '../core/BaseHttpRequest'; - -export class ViewService { - - constructor(public readonly httpRequest: BaseHttpRequest) {} - - /** - * Execute view function of a module - * Execute the Move function with the given parameters and return its execution result. - * - * The Aptos nodes prune account state history, via a configurable time window. - * If the requested ledger version has been pruned, the server responds with a 410. - * @param requestBody - * @param ledgerVersion Ledger version to get state of account - * - * If not provided, it will be the latest version - * @returns MoveValue - * @throws ApiError - */ - public view( - requestBody: ViewRequest, - ledgerVersion?: U64, - ): CancelablePromise> { - return this.httpRequest.request({ - method: 'POST', - url: '/view', - query: { - 'ledger_version': ledgerVersion, - }, - body: requestBody, - mediaType: 'application/json', - }); - } - -} diff --git a/m1/JavaScript-client/src/index.ts b/m1/JavaScript-client/src/index.ts deleted file mode 100644 index 6e1cbbf76..000000000 --- a/m1/JavaScript-client/src/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -export * from "./account"; -export * from "./providers"; -export * as BCS from "./bcs"; -export * from "./utils/hex_string"; -export * from "./plugins"; -export * from "./transaction_builder"; -export * as TokenTypes from "./aptos_types/token_types"; -export * as Types from "./generated/index"; -export { derivePath } from "./utils/hd-key"; -export { - deserializePropertyMap, - deserializeValueBasedOnTypeTag, - getPropertyValueRaw, -} from "./utils/property_map_serde"; -export { Network, CustomEndpoints } from "./utils/api-endpoints"; diff --git a/m1/JavaScript-client/src/indexer/codegen.yml b/m1/JavaScript-client/src/indexer/codegen.yml deleted file mode 100644 index a9e72503f..000000000 --- a/m1/JavaScript-client/src/indexer/codegen.yml +++ /dev/null @@ -1,22 +0,0 @@ -overwrite: true -documents: src/indexer/queries/**/*.graphql -schema: https://indexer.mainnet.aptoslabs.com/v1/graphql -generates: - src/indexer/generated/types.ts: - plugins: - - typescript - src/indexer/generated/operations.ts: - preset: import-types-preset - presetConfig: - typesPath: ./types - plugins: - - typescript-operations - src/indexer/generated/queries.ts: - preset: import-types-preset - presetConfig: - typesPath: ./operations - plugins: - - typescript-graphql-request - config: - documentMode: string - documentVariableSuffix: "" diff --git a/m1/JavaScript-client/src/indexer/generated/operations.ts b/m1/JavaScript-client/src/indexer/generated/operations.ts deleted file mode 100644 index 361f2a666..000000000 --- a/m1/JavaScript-client/src/indexer/generated/operations.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as Types from './types'; - -export type GetAccountCoinsDataQueryVariables = Types.Exact<{ - owner_address?: Types.InputMaybe; - offset?: Types.InputMaybe; - limit?: Types.InputMaybe; -}>; - - -export type GetAccountCoinsDataQuery = { __typename?: 'query_root', current_coin_balances: Array<{ __typename?: 'current_coin_balances', amount: any, coin_type: string, coin_info?: { __typename?: 'coin_infos', name: string, decimals: number, symbol: string } | null }> }; - -export type GetAccountCurrentTokensQueryVariables = Types.Exact<{ - address: Types.Scalars['String']; - offset?: Types.InputMaybe; - limit?: Types.InputMaybe; -}>; - - -export type GetAccountCurrentTokensQuery = { __typename?: 'query_root', current_token_ownerships: Array<{ __typename?: 'current_token_ownerships', amount: any, last_transaction_version: any, property_version: any, current_token_data?: { __typename?: 'current_token_datas', creator_address: string, collection_name: string, description: string, metadata_uri: string, name: string, token_data_id_hash: string, collection_data_id_hash: string } | null, current_collection_data?: { __typename?: 'current_collection_datas', metadata_uri: string, supply: any, description: string, collection_name: string, collection_data_id_hash: string, table_handle: string, creator_address: string } | null }> }; - -export type TokenDataFieldsFragment = { __typename?: 'current_token_datas', creator_address: string, collection_name: string, description: string, metadata_uri: string, name: string, token_data_id_hash: string, collection_data_id_hash: string }; - -export type CollectionDataFieldsFragment = { __typename?: 'current_collection_datas', metadata_uri: string, supply: any, description: string, collection_name: string, collection_data_id_hash: string, table_handle: string, creator_address: string }; - -export type GetAccountTokensCountQueryVariables = Types.Exact<{ - owner_address?: Types.InputMaybe; -}>; - - -export type GetAccountTokensCountQuery = { __typename?: 'query_root', current_token_ownerships_aggregate: { __typename?: 'current_token_ownerships_aggregate', aggregate?: { __typename?: 'current_token_ownerships_aggregate_fields', count: number } | null } }; - -export type GetAccountTransactionsCountQueryVariables = Types.Exact<{ - address?: Types.InputMaybe; -}>; - - -export type GetAccountTransactionsCountQuery = { __typename?: 'query_root', move_resources_aggregate: { __typename?: 'move_resources_aggregate', aggregate?: { __typename?: 'move_resources_aggregate_fields', count: number } | null } }; - -export type GetAccountTransactionsDataQueryVariables = Types.Exact<{ - address?: Types.InputMaybe; - limit?: Types.InputMaybe; - offset?: Types.InputMaybe; -}>; - - -export type GetAccountTransactionsDataQuery = { __typename?: 'query_root', move_resources: Array<{ __typename?: 'move_resources', transaction_version: any }> }; - -export type GetCurrentDelegatorBalancesCountQueryVariables = Types.Exact<{ - poolAddress?: Types.InputMaybe; -}>; - - -export type GetCurrentDelegatorBalancesCountQuery = { __typename?: 'query_root', current_delegator_balances_aggregate: { __typename?: 'current_delegator_balances_aggregate', aggregate?: { __typename?: 'current_delegator_balances_aggregate_fields', count: number } | null } }; - -export type GetDelegatedStakingActivitiesQueryVariables = Types.Exact<{ - delegatorAddress?: Types.InputMaybe; - poolAddress?: Types.InputMaybe; -}>; - - -export type GetDelegatedStakingActivitiesQuery = { __typename?: 'query_root', delegated_staking_activities: Array<{ __typename?: 'delegated_staking_activities', amount: any, delegator_address: string, event_index: any, event_type: string, pool_address: string, transaction_version: any }> }; - -export type GetIndexerLedgerInfoQueryVariables = Types.Exact<{ [key: string]: never; }>; - - -export type GetIndexerLedgerInfoQuery = { __typename?: 'query_root', ledger_infos: Array<{ __typename?: 'ledger_infos', chain_id: any }> }; - -export type GetTokenActivitiesQueryVariables = Types.Exact<{ - idHash: Types.Scalars['String']; - offset?: Types.InputMaybe; - limit?: Types.InputMaybe; -}>; - - -export type GetTokenActivitiesQuery = { __typename?: 'query_root', token_activities: Array<{ __typename?: 'token_activities', creator_address: string, collection_name: string, name: string, token_data_id_hash: string, collection_data_id_hash: string, from_address?: string | null, to_address?: string | null, transaction_version: any, transaction_timestamp: any, property_version: any, transfer_type: string, event_sequence_number: any, token_amount: any }> }; - -export type GetTokenActivitiesCountQueryVariables = Types.Exact<{ - token_id?: Types.InputMaybe; -}>; - - -export type GetTokenActivitiesCountQuery = { __typename?: 'query_root', token_activities_aggregate: { __typename?: 'token_activities_aggregate', aggregate?: { __typename?: 'token_activities_aggregate_fields', count: number } | null } }; - -export type GetTokenDataQueryVariables = Types.Exact<{ - token_id?: Types.InputMaybe; -}>; - - -export type GetTokenDataQuery = { __typename?: 'query_root', current_token_datas: Array<{ __typename?: 'current_token_datas', token_data_id_hash: string, name: string, collection_name: string, creator_address: string, default_properties: any, largest_property_version: any, maximum: any, metadata_uri: string, payee_address: string, royalty_points_denominator: any, royalty_points_numerator: any, supply: any }> }; - -export type GetTokenOwnersDataQueryVariables = Types.Exact<{ - token_id?: Types.InputMaybe; - property_version?: Types.InputMaybe; -}>; - - -export type GetTokenOwnersDataQuery = { __typename?: 'query_root', current_token_ownerships: Array<{ __typename?: 'current_token_ownerships', owner_address: string }> }; - -export type GetTopUserTransactionsQueryVariables = Types.Exact<{ - limit?: Types.InputMaybe; -}>; - - -export type GetTopUserTransactionsQuery = { __typename?: 'query_root', user_transactions: Array<{ __typename?: 'user_transactions', version: any }> }; - -export type GetUserTransactionsQueryVariables = Types.Exact<{ - limit?: Types.InputMaybe; - start_version?: Types.InputMaybe; - offset?: Types.InputMaybe; -}>; - - -export type GetUserTransactionsQuery = { __typename?: 'query_root', user_transactions: Array<{ __typename?: 'user_transactions', version: any }> }; diff --git a/m1/JavaScript-client/src/indexer/generated/queries.ts b/m1/JavaScript-client/src/indexer/generated/queries.ts deleted file mode 100644 index 9ef4ccac4..000000000 --- a/m1/JavaScript-client/src/indexer/generated/queries.ts +++ /dev/null @@ -1,265 +0,0 @@ -import * as Types from './operations'; - -import { GraphQLClient } from 'graphql-request'; -import * as Dom from 'graphql-request/dist/types.dom'; -export const TokenDataFieldsFragmentDoc = ` - fragment TokenDataFields on current_token_datas { - creator_address - collection_name - description - metadata_uri - name - token_data_id_hash - collection_data_id_hash -} - `; -export const CollectionDataFieldsFragmentDoc = ` - fragment CollectionDataFields on current_collection_datas { - metadata_uri - supply - description - collection_name - collection_data_id_hash - table_handle - creator_address -} - `; -export const GetAccountCoinsData = ` - query getAccountCoinsData($owner_address: String, $offset: Int, $limit: Int) { - current_coin_balances( - where: {owner_address: {_eq: $owner_address}} - offset: $offset - limit: $limit - ) { - amount - coin_type - coin_info { - name - decimals - symbol - } - } -} - `; -export const GetAccountCurrentTokens = ` - query getAccountCurrentTokens($address: String!, $offset: Int, $limit: Int) { - current_token_ownerships( - where: {owner_address: {_eq: $address}, amount: {_gt: 0}} - order_by: [{last_transaction_version: desc}, {creator_address: asc}, {collection_name: asc}, {name: asc}] - offset: $offset - limit: $limit - ) { - amount - current_token_data { - ...TokenDataFields - } - current_collection_data { - ...CollectionDataFields - } - last_transaction_version - property_version - } -} - ${TokenDataFieldsFragmentDoc} -${CollectionDataFieldsFragmentDoc}`; -export const GetAccountTokensCount = ` - query getAccountTokensCount($owner_address: String) { - current_token_ownerships_aggregate( - where: {owner_address: {_eq: $owner_address}, amount: {_gt: "0"}} - ) { - aggregate { - count - } - } -} - `; -export const GetAccountTransactionsCount = ` - query getAccountTransactionsCount($address: String) { - move_resources_aggregate( - where: {address: {_eq: $address}} - distinct_on: transaction_version - ) { - aggregate { - count - } - } -} - `; -export const GetAccountTransactionsData = ` - query getAccountTransactionsData($address: String, $limit: Int, $offset: Int) { - move_resources( - where: {address: {_eq: $address}} - order_by: {transaction_version: desc} - distinct_on: transaction_version - limit: $limit - offset: $offset - ) { - transaction_version - } -} - `; -export const GetCurrentDelegatorBalancesCount = ` - query getCurrentDelegatorBalancesCount($poolAddress: String) { - current_delegator_balances_aggregate( - where: {pool_type: {_eq: "active_shares"}, pool_address: {_eq: $poolAddress}, amount: {_gt: "0"}} - distinct_on: delegator_address - ) { - aggregate { - count - } - } -} - `; -export const GetDelegatedStakingActivities = ` - query getDelegatedStakingActivities($delegatorAddress: String, $poolAddress: String) { - delegated_staking_activities( - where: {delegator_address: {_eq: $delegatorAddress}, pool_address: {_eq: $poolAddress}} - ) { - amount - delegator_address - event_index - event_type - pool_address - transaction_version - } -} - `; -export const GetIndexerLedgerInfo = ` - query getIndexerLedgerInfo { - ledger_infos { - chain_id - } -} - `; -export const GetTokenActivities = ` - query getTokenActivities($idHash: String!, $offset: Int, $limit: Int) { - token_activities( - where: {token_data_id_hash: {_eq: $idHash}} - order_by: {transaction_version: desc} - offset: $offset - limit: $limit - ) { - creator_address - collection_name - name - token_data_id_hash - collection_data_id_hash - from_address - to_address - transaction_version - transaction_timestamp - property_version - transfer_type - event_sequence_number - token_amount - } -} - `; -export const GetTokenActivitiesCount = ` - query getTokenActivitiesCount($token_id: String) { - token_activities_aggregate(where: {token_data_id_hash: {_eq: $token_id}}) { - aggregate { - count - } - } -} - `; -export const GetTokenData = ` - query getTokenData($token_id: String) { - current_token_datas(where: {token_data_id_hash: {_eq: $token_id}}) { - token_data_id_hash - name - collection_name - creator_address - default_properties - largest_property_version - maximum - metadata_uri - payee_address - royalty_points_denominator - royalty_points_numerator - supply - } -} - `; -export const GetTokenOwnersData = ` - query getTokenOwnersData($token_id: String, $property_version: numeric) { - current_token_ownerships( - where: {token_data_id_hash: {_eq: $token_id}, property_version: {_eq: $property_version}} - ) { - owner_address - } -} - `; -export const GetTopUserTransactions = ` - query getTopUserTransactions($limit: Int) { - user_transactions(limit: $limit, order_by: {version: desc}) { - version - } -} - `; -export const GetUserTransactions = ` - query getUserTransactions($limit: Int, $start_version: bigint, $offset: Int) { - user_transactions( - limit: $limit - order_by: {version: desc} - where: {version: {_lte: $start_version}} - offset: $offset - ) { - version - } -} - `; - -export type SdkFunctionWrapper = (action: (requestHeaders?:Record) => Promise, operationName: string, operationType?: string) => Promise; - - -const defaultWrapper: SdkFunctionWrapper = (action, _operationName, _operationType) => action(); - -export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = defaultWrapper) { - return { - getAccountCoinsData(variables?: Types.GetAccountCoinsDataQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetAccountCoinsData, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getAccountCoinsData', 'query'); - }, - getAccountCurrentTokens(variables: Types.GetAccountCurrentTokensQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetAccountCurrentTokens, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getAccountCurrentTokens', 'query'); - }, - getAccountTokensCount(variables?: Types.GetAccountTokensCountQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetAccountTokensCount, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getAccountTokensCount', 'query'); - }, - getAccountTransactionsCount(variables?: Types.GetAccountTransactionsCountQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetAccountTransactionsCount, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getAccountTransactionsCount', 'query'); - }, - getAccountTransactionsData(variables?: Types.GetAccountTransactionsDataQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetAccountTransactionsData, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getAccountTransactionsData', 'query'); - }, - getCurrentDelegatorBalancesCount(variables?: Types.GetCurrentDelegatorBalancesCountQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetCurrentDelegatorBalancesCount, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getCurrentDelegatorBalancesCount', 'query'); - }, - getDelegatedStakingActivities(variables?: Types.GetDelegatedStakingActivitiesQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetDelegatedStakingActivities, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getDelegatedStakingActivities', 'query'); - }, - getIndexerLedgerInfo(variables?: Types.GetIndexerLedgerInfoQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetIndexerLedgerInfo, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getIndexerLedgerInfo', 'query'); - }, - getTokenActivities(variables: Types.GetTokenActivitiesQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetTokenActivities, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTokenActivities', 'query'); - }, - getTokenActivitiesCount(variables?: Types.GetTokenActivitiesCountQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetTokenActivitiesCount, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTokenActivitiesCount', 'query'); - }, - getTokenData(variables?: Types.GetTokenDataQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetTokenData, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTokenData', 'query'); - }, - getTokenOwnersData(variables?: Types.GetTokenOwnersDataQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetTokenOwnersData, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTokenOwnersData', 'query'); - }, - getTopUserTransactions(variables?: Types.GetTopUserTransactionsQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetTopUserTransactions, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTopUserTransactions', 'query'); - }, - getUserTransactions(variables?: Types.GetUserTransactionsQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { - return withWrapper((wrappedRequestHeaders) => client.request(GetUserTransactions, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getUserTransactions', 'query'); - } - }; -} -export type Sdk = ReturnType; \ No newline at end of file diff --git a/m1/JavaScript-client/src/indexer/generated/types.ts b/m1/JavaScript-client/src/indexer/generated/types.ts deleted file mode 100644 index 524660678..000000000 --- a/m1/JavaScript-client/src/indexer/generated/types.ts +++ /dev/null @@ -1,4975 +0,0 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: string; - String: string; - Boolean: boolean; - Int: number; - Float: number; - bigint: any; - jsonb: any; - numeric: any; - timestamp: any; -}; - -/** Boolean expression to compare columns of type "Boolean". All fields are combined with logical 'AND'. */ -export type Boolean_Comparison_Exp = { - _eq?: InputMaybe; - _gt?: InputMaybe; - _gte?: InputMaybe; - _in?: InputMaybe>; - _is_null?: InputMaybe; - _lt?: InputMaybe; - _lte?: InputMaybe; - _neq?: InputMaybe; - _nin?: InputMaybe>; -}; - -/** Boolean expression to compare columns of type "Int". All fields are combined with logical 'AND'. */ -export type Int_Comparison_Exp = { - _eq?: InputMaybe; - _gt?: InputMaybe; - _gte?: InputMaybe; - _in?: InputMaybe>; - _is_null?: InputMaybe; - _lt?: InputMaybe; - _lte?: InputMaybe; - _neq?: InputMaybe; - _nin?: InputMaybe>; -}; - -/** Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'. */ -export type String_Comparison_Exp = { - _eq?: InputMaybe; - _gt?: InputMaybe; - _gte?: InputMaybe; - /** does the column match the given case-insensitive pattern */ - _ilike?: InputMaybe; - _in?: InputMaybe>; - /** does the column match the given POSIX regular expression, case insensitive */ - _iregex?: InputMaybe; - _is_null?: InputMaybe; - /** does the column match the given pattern */ - _like?: InputMaybe; - _lt?: InputMaybe; - _lte?: InputMaybe; - _neq?: InputMaybe; - /** does the column NOT match the given case-insensitive pattern */ - _nilike?: InputMaybe; - _nin?: InputMaybe>; - /** does the column NOT match the given POSIX regular expression, case insensitive */ - _niregex?: InputMaybe; - /** does the column NOT match the given pattern */ - _nlike?: InputMaybe; - /** does the column NOT match the given POSIX regular expression, case sensitive */ - _nregex?: InputMaybe; - /** does the column NOT match the given SQL regular expression */ - _nsimilar?: InputMaybe; - /** does the column match the given POSIX regular expression, case sensitive */ - _regex?: InputMaybe; - /** does the column match the given SQL regular expression */ - _similar?: InputMaybe; -}; - -/** columns and relationships of "address_version_from_events" */ -export type Address_Version_From_Events = { - __typename?: 'address_version_from_events'; - account_address?: Maybe; - coin_activities: Array; - token_activities: Array; - token_activities_aggregate: Token_Activities_Aggregate; - transaction_version?: Maybe; -}; - - -/** columns and relationships of "address_version_from_events" */ -export type Address_Version_From_EventsCoin_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -/** columns and relationships of "address_version_from_events" */ -export type Address_Version_From_EventsToken_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -/** columns and relationships of "address_version_from_events" */ -export type Address_Version_From_EventsToken_Activities_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "address_version_from_events". All fields are combined with a logical 'AND'. */ -export type Address_Version_From_Events_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - account_address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Ordering options when selecting data from "address_version_from_events". */ -export type Address_Version_From_Events_Order_By = { - account_address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "address_version_from_events" */ -export enum Address_Version_From_Events_Select_Column { - /** column name */ - AccountAddress = 'account_address', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** Streaming cursor of the table "address_version_from_events" */ -export type Address_Version_From_Events_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Address_Version_From_Events_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Address_Version_From_Events_Stream_Cursor_Value_Input = { - account_address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Boolean expression to compare columns of type "bigint". All fields are combined with logical 'AND'. */ -export type Bigint_Comparison_Exp = { - _eq?: InputMaybe; - _gt?: InputMaybe; - _gte?: InputMaybe; - _in?: InputMaybe>; - _is_null?: InputMaybe; - _lt?: InputMaybe; - _lte?: InputMaybe; - _neq?: InputMaybe; - _nin?: InputMaybe>; -}; - -/** columns and relationships of "coin_activities" */ -export type Coin_Activities = { - __typename?: 'coin_activities'; - activity_type: Scalars['String']; - amount: Scalars['numeric']; - block_height: Scalars['bigint']; - coin_type: Scalars['String']; - entry_function_id_str?: Maybe; - event_account_address: Scalars['String']; - event_creation_number: Scalars['bigint']; - event_index?: Maybe; - event_sequence_number: Scalars['bigint']; - is_gas_fee: Scalars['Boolean']; - is_transaction_success: Scalars['Boolean']; - owner_address: Scalars['String']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "coin_activities". All fields are combined with a logical 'AND'. */ -export type Coin_Activities_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - activity_type?: InputMaybe; - amount?: InputMaybe; - block_height?: InputMaybe; - coin_type?: InputMaybe; - entry_function_id_str?: InputMaybe; - event_account_address?: InputMaybe; - event_creation_number?: InputMaybe; - event_index?: InputMaybe; - event_sequence_number?: InputMaybe; - is_gas_fee?: InputMaybe; - is_transaction_success?: InputMaybe; - owner_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Ordering options when selecting data from "coin_activities". */ -export type Coin_Activities_Order_By = { - activity_type?: InputMaybe; - amount?: InputMaybe; - block_height?: InputMaybe; - coin_type?: InputMaybe; - entry_function_id_str?: InputMaybe; - event_account_address?: InputMaybe; - event_creation_number?: InputMaybe; - event_index?: InputMaybe; - event_sequence_number?: InputMaybe; - is_gas_fee?: InputMaybe; - is_transaction_success?: InputMaybe; - owner_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "coin_activities" */ -export enum Coin_Activities_Select_Column { - /** column name */ - ActivityType = 'activity_type', - /** column name */ - Amount = 'amount', - /** column name */ - BlockHeight = 'block_height', - /** column name */ - CoinType = 'coin_type', - /** column name */ - EntryFunctionIdStr = 'entry_function_id_str', - /** column name */ - EventAccountAddress = 'event_account_address', - /** column name */ - EventCreationNumber = 'event_creation_number', - /** column name */ - EventIndex = 'event_index', - /** column name */ - EventSequenceNumber = 'event_sequence_number', - /** column name */ - IsGasFee = 'is_gas_fee', - /** column name */ - IsTransactionSuccess = 'is_transaction_success', - /** column name */ - OwnerAddress = 'owner_address', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** Streaming cursor of the table "coin_activities" */ -export type Coin_Activities_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Coin_Activities_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Coin_Activities_Stream_Cursor_Value_Input = { - activity_type?: InputMaybe; - amount?: InputMaybe; - block_height?: InputMaybe; - coin_type?: InputMaybe; - entry_function_id_str?: InputMaybe; - event_account_address?: InputMaybe; - event_creation_number?: InputMaybe; - event_index?: InputMaybe; - event_sequence_number?: InputMaybe; - is_gas_fee?: InputMaybe; - is_transaction_success?: InputMaybe; - owner_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** columns and relationships of "coin_balances" */ -export type Coin_Balances = { - __typename?: 'coin_balances'; - amount: Scalars['numeric']; - coin_type: Scalars['String']; - coin_type_hash: Scalars['String']; - owner_address: Scalars['String']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "coin_balances". All fields are combined with a logical 'AND'. */ -export type Coin_Balances_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - amount?: InputMaybe; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - owner_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Ordering options when selecting data from "coin_balances". */ -export type Coin_Balances_Order_By = { - amount?: InputMaybe; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - owner_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "coin_balances" */ -export enum Coin_Balances_Select_Column { - /** column name */ - Amount = 'amount', - /** column name */ - CoinType = 'coin_type', - /** column name */ - CoinTypeHash = 'coin_type_hash', - /** column name */ - OwnerAddress = 'owner_address', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** Streaming cursor of the table "coin_balances" */ -export type Coin_Balances_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Coin_Balances_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Coin_Balances_Stream_Cursor_Value_Input = { - amount?: InputMaybe; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - owner_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** columns and relationships of "coin_infos" */ -export type Coin_Infos = { - __typename?: 'coin_infos'; - coin_type: Scalars['String']; - coin_type_hash: Scalars['String']; - creator_address: Scalars['String']; - decimals: Scalars['Int']; - name: Scalars['String']; - supply_aggregator_table_handle?: Maybe; - supply_aggregator_table_key?: Maybe; - symbol: Scalars['String']; - transaction_created_timestamp: Scalars['timestamp']; - transaction_version_created: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "coin_infos". All fields are combined with a logical 'AND'. */ -export type Coin_Infos_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - creator_address?: InputMaybe; - decimals?: InputMaybe; - name?: InputMaybe; - supply_aggregator_table_handle?: InputMaybe; - supply_aggregator_table_key?: InputMaybe; - symbol?: InputMaybe; - transaction_created_timestamp?: InputMaybe; - transaction_version_created?: InputMaybe; -}; - -/** Ordering options when selecting data from "coin_infos". */ -export type Coin_Infos_Order_By = { - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - creator_address?: InputMaybe; - decimals?: InputMaybe; - name?: InputMaybe; - supply_aggregator_table_handle?: InputMaybe; - supply_aggregator_table_key?: InputMaybe; - symbol?: InputMaybe; - transaction_created_timestamp?: InputMaybe; - transaction_version_created?: InputMaybe; -}; - -/** select columns of table "coin_infos" */ -export enum Coin_Infos_Select_Column { - /** column name */ - CoinType = 'coin_type', - /** column name */ - CoinTypeHash = 'coin_type_hash', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - Decimals = 'decimals', - /** column name */ - Name = 'name', - /** column name */ - SupplyAggregatorTableHandle = 'supply_aggregator_table_handle', - /** column name */ - SupplyAggregatorTableKey = 'supply_aggregator_table_key', - /** column name */ - Symbol = 'symbol', - /** column name */ - TransactionCreatedTimestamp = 'transaction_created_timestamp', - /** column name */ - TransactionVersionCreated = 'transaction_version_created' -} - -/** Streaming cursor of the table "coin_infos" */ -export type Coin_Infos_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Coin_Infos_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Coin_Infos_Stream_Cursor_Value_Input = { - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - creator_address?: InputMaybe; - decimals?: InputMaybe; - name?: InputMaybe; - supply_aggregator_table_handle?: InputMaybe; - supply_aggregator_table_key?: InputMaybe; - symbol?: InputMaybe; - transaction_created_timestamp?: InputMaybe; - transaction_version_created?: InputMaybe; -}; - -/** columns and relationships of "coin_supply" */ -export type Coin_Supply = { - __typename?: 'coin_supply'; - coin_type: Scalars['String']; - coin_type_hash: Scalars['String']; - supply: Scalars['numeric']; - transaction_epoch: Scalars['bigint']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "coin_supply". All fields are combined with a logical 'AND'. */ -export type Coin_Supply_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - supply?: InputMaybe; - transaction_epoch?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Ordering options when selecting data from "coin_supply". */ -export type Coin_Supply_Order_By = { - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - supply?: InputMaybe; - transaction_epoch?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "coin_supply" */ -export enum Coin_Supply_Select_Column { - /** column name */ - CoinType = 'coin_type', - /** column name */ - CoinTypeHash = 'coin_type_hash', - /** column name */ - Supply = 'supply', - /** column name */ - TransactionEpoch = 'transaction_epoch', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** Streaming cursor of the table "coin_supply" */ -export type Coin_Supply_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Coin_Supply_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Coin_Supply_Stream_Cursor_Value_Input = { - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - supply?: InputMaybe; - transaction_epoch?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** columns and relationships of "collection_datas" */ -export type Collection_Datas = { - __typename?: 'collection_datas'; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - description: Scalars['String']; - description_mutable: Scalars['Boolean']; - maximum: Scalars['numeric']; - maximum_mutable: Scalars['Boolean']; - metadata_uri: Scalars['String']; - supply: Scalars['numeric']; - table_handle: Scalars['String']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; - uri_mutable: Scalars['Boolean']; -}; - -/** Boolean expression to filter rows from the table "collection_datas". All fields are combined with a logical 'AND'. */ -export type Collection_Datas_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - supply?: InputMaybe; - table_handle?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** Ordering options when selecting data from "collection_datas". */ -export type Collection_Datas_Order_By = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - supply?: InputMaybe; - table_handle?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** select columns of table "collection_datas" */ -export enum Collection_Datas_Select_Column { - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - Description = 'description', - /** column name */ - DescriptionMutable = 'description_mutable', - /** column name */ - Maximum = 'maximum', - /** column name */ - MaximumMutable = 'maximum_mutable', - /** column name */ - MetadataUri = 'metadata_uri', - /** column name */ - Supply = 'supply', - /** column name */ - TableHandle = 'table_handle', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version', - /** column name */ - UriMutable = 'uri_mutable' -} - -/** Streaming cursor of the table "collection_datas" */ -export type Collection_Datas_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Collection_Datas_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Collection_Datas_Stream_Cursor_Value_Input = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - supply?: InputMaybe; - table_handle?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** columns and relationships of "current_ans_lookup" */ -export type Current_Ans_Lookup = { - __typename?: 'current_ans_lookup'; - /** An array relationship */ - all_token_ownerships: Array; - /** An aggregate relationship */ - all_token_ownerships_aggregate: Current_Token_Ownerships_Aggregate; - domain: Scalars['String']; - expiration_timestamp: Scalars['timestamp']; - last_transaction_version: Scalars['bigint']; - registered_address?: Maybe; - subdomain: Scalars['String']; -}; - - -/** columns and relationships of "current_ans_lookup" */ -export type Current_Ans_LookupAll_Token_OwnershipsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -/** columns and relationships of "current_ans_lookup" */ -export type Current_Ans_LookupAll_Token_Ownerships_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "current_ans_lookup". All fields are combined with a logical 'AND'. */ -export type Current_Ans_Lookup_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - all_token_ownerships?: InputMaybe; - domain?: InputMaybe; - expiration_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - registered_address?: InputMaybe; - subdomain?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_ans_lookup". */ -export type Current_Ans_Lookup_Order_By = { - all_token_ownerships_aggregate?: InputMaybe; - domain?: InputMaybe; - expiration_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - registered_address?: InputMaybe; - subdomain?: InputMaybe; -}; - -/** select columns of table "current_ans_lookup" */ -export enum Current_Ans_Lookup_Select_Column { - /** column name */ - Domain = 'domain', - /** column name */ - ExpirationTimestamp = 'expiration_timestamp', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - RegisteredAddress = 'registered_address', - /** column name */ - Subdomain = 'subdomain' -} - -/** Streaming cursor of the table "current_ans_lookup" */ -export type Current_Ans_Lookup_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Ans_Lookup_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Ans_Lookup_Stream_Cursor_Value_Input = { - domain?: InputMaybe; - expiration_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - registered_address?: InputMaybe; - subdomain?: InputMaybe; -}; - -/** columns and relationships of "current_coin_balances" */ -export type Current_Coin_Balances = { - __typename?: 'current_coin_balances'; - amount: Scalars['numeric']; - /** An object relationship */ - coin_info?: Maybe; - coin_type: Scalars['String']; - coin_type_hash: Scalars['String']; - last_transaction_timestamp: Scalars['timestamp']; - last_transaction_version: Scalars['bigint']; - owner_address: Scalars['String']; -}; - -/** Boolean expression to filter rows from the table "current_coin_balances". All fields are combined with a logical 'AND'. */ -export type Current_Coin_Balances_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - amount?: InputMaybe; - coin_info?: InputMaybe; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - owner_address?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_coin_balances". */ -export type Current_Coin_Balances_Order_By = { - amount?: InputMaybe; - coin_info?: InputMaybe; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - owner_address?: InputMaybe; -}; - -/** select columns of table "current_coin_balances" */ -export enum Current_Coin_Balances_Select_Column { - /** column name */ - Amount = 'amount', - /** column name */ - CoinType = 'coin_type', - /** column name */ - CoinTypeHash = 'coin_type_hash', - /** column name */ - LastTransactionTimestamp = 'last_transaction_timestamp', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - OwnerAddress = 'owner_address' -} - -/** Streaming cursor of the table "current_coin_balances" */ -export type Current_Coin_Balances_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Coin_Balances_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Coin_Balances_Stream_Cursor_Value_Input = { - amount?: InputMaybe; - coin_type?: InputMaybe; - coin_type_hash?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - owner_address?: InputMaybe; -}; - -/** columns and relationships of "current_collection_datas" */ -export type Current_Collection_Datas = { - __typename?: 'current_collection_datas'; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - description: Scalars['String']; - description_mutable: Scalars['Boolean']; - last_transaction_timestamp: Scalars['timestamp']; - last_transaction_version: Scalars['bigint']; - maximum: Scalars['numeric']; - maximum_mutable: Scalars['Boolean']; - metadata_uri: Scalars['String']; - supply: Scalars['numeric']; - table_handle: Scalars['String']; - uri_mutable: Scalars['Boolean']; -}; - -/** Boolean expression to filter rows from the table "current_collection_datas". All fields are combined with a logical 'AND'. */ -export type Current_Collection_Datas_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - supply?: InputMaybe; - table_handle?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_collection_datas". */ -export type Current_Collection_Datas_Order_By = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - supply?: InputMaybe; - table_handle?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** select columns of table "current_collection_datas" */ -export enum Current_Collection_Datas_Select_Column { - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - Description = 'description', - /** column name */ - DescriptionMutable = 'description_mutable', - /** column name */ - LastTransactionTimestamp = 'last_transaction_timestamp', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - Maximum = 'maximum', - /** column name */ - MaximumMutable = 'maximum_mutable', - /** column name */ - MetadataUri = 'metadata_uri', - /** column name */ - Supply = 'supply', - /** column name */ - TableHandle = 'table_handle', - /** column name */ - UriMutable = 'uri_mutable' -} - -/** Streaming cursor of the table "current_collection_datas" */ -export type Current_Collection_Datas_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Collection_Datas_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Collection_Datas_Stream_Cursor_Value_Input = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - supply?: InputMaybe; - table_handle?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** columns and relationships of "current_collection_ownership_view" */ -export type Current_Collection_Ownership_View = { - __typename?: 'current_collection_ownership_view'; - collection_data_id_hash?: Maybe; - collection_name?: Maybe; - creator_address?: Maybe; - distinct_tokens?: Maybe; - last_transaction_version?: Maybe; - owner_address?: Maybe; -}; - -/** Boolean expression to filter rows from the table "current_collection_ownership_view". All fields are combined with a logical 'AND'. */ -export type Current_Collection_Ownership_View_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - distinct_tokens?: InputMaybe; - last_transaction_version?: InputMaybe; - owner_address?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_collection_ownership_view". */ -export type Current_Collection_Ownership_View_Order_By = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - distinct_tokens?: InputMaybe; - last_transaction_version?: InputMaybe; - owner_address?: InputMaybe; -}; - -/** select columns of table "current_collection_ownership_view" */ -export enum Current_Collection_Ownership_View_Select_Column { - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - DistinctTokens = 'distinct_tokens', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - OwnerAddress = 'owner_address' -} - -/** Streaming cursor of the table "current_collection_ownership_view" */ -export type Current_Collection_Ownership_View_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Collection_Ownership_View_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Collection_Ownership_View_Stream_Cursor_Value_Input = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - distinct_tokens?: InputMaybe; - last_transaction_version?: InputMaybe; - owner_address?: InputMaybe; -}; - -/** columns and relationships of "current_delegator_balances" */ -export type Current_Delegator_Balances = { - __typename?: 'current_delegator_balances'; - amount: Scalars['numeric']; - delegator_address: Scalars['String']; - last_transaction_version: Scalars['bigint']; - pool_address: Scalars['String']; - pool_type: Scalars['String']; - table_handle: Scalars['String']; -}; - -/** aggregated selection of "current_delegator_balances" */ -export type Current_Delegator_Balances_Aggregate = { - __typename?: 'current_delegator_balances_aggregate'; - aggregate?: Maybe; - nodes: Array; -}; - -/** aggregate fields of "current_delegator_balances" */ -export type Current_Delegator_Balances_Aggregate_Fields = { - __typename?: 'current_delegator_balances_aggregate_fields'; - avg?: Maybe; - count: Scalars['Int']; - max?: Maybe; - min?: Maybe; - stddev?: Maybe; - stddev_pop?: Maybe; - stddev_samp?: Maybe; - sum?: Maybe; - var_pop?: Maybe; - var_samp?: Maybe; - variance?: Maybe; -}; - - -/** aggregate fields of "current_delegator_balances" */ -export type Current_Delegator_Balances_Aggregate_FieldsCountArgs = { - columns?: InputMaybe>; - distinct?: InputMaybe; -}; - -/** aggregate avg on columns */ -export type Current_Delegator_Balances_Avg_Fields = { - __typename?: 'current_delegator_balances_avg_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** Boolean expression to filter rows from the table "current_delegator_balances". All fields are combined with a logical 'AND'. */ -export type Current_Delegator_Balances_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - amount?: InputMaybe; - delegator_address?: InputMaybe; - last_transaction_version?: InputMaybe; - pool_address?: InputMaybe; - pool_type?: InputMaybe; - table_handle?: InputMaybe; -}; - -/** aggregate max on columns */ -export type Current_Delegator_Balances_Max_Fields = { - __typename?: 'current_delegator_balances_max_fields'; - amount?: Maybe; - delegator_address?: Maybe; - last_transaction_version?: Maybe; - pool_address?: Maybe; - pool_type?: Maybe; - table_handle?: Maybe; -}; - -/** aggregate min on columns */ -export type Current_Delegator_Balances_Min_Fields = { - __typename?: 'current_delegator_balances_min_fields'; - amount?: Maybe; - delegator_address?: Maybe; - last_transaction_version?: Maybe; - pool_address?: Maybe; - pool_type?: Maybe; - table_handle?: Maybe; -}; - -/** Ordering options when selecting data from "current_delegator_balances". */ -export type Current_Delegator_Balances_Order_By = { - amount?: InputMaybe; - delegator_address?: InputMaybe; - last_transaction_version?: InputMaybe; - pool_address?: InputMaybe; - pool_type?: InputMaybe; - table_handle?: InputMaybe; -}; - -/** select columns of table "current_delegator_balances" */ -export enum Current_Delegator_Balances_Select_Column { - /** column name */ - Amount = 'amount', - /** column name */ - DelegatorAddress = 'delegator_address', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - PoolAddress = 'pool_address', - /** column name */ - PoolType = 'pool_type', - /** column name */ - TableHandle = 'table_handle' -} - -/** aggregate stddev on columns */ -export type Current_Delegator_Balances_Stddev_Fields = { - __typename?: 'current_delegator_balances_stddev_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** aggregate stddev_pop on columns */ -export type Current_Delegator_Balances_Stddev_Pop_Fields = { - __typename?: 'current_delegator_balances_stddev_pop_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** aggregate stddev_samp on columns */ -export type Current_Delegator_Balances_Stddev_Samp_Fields = { - __typename?: 'current_delegator_balances_stddev_samp_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** Streaming cursor of the table "current_delegator_balances" */ -export type Current_Delegator_Balances_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Delegator_Balances_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Delegator_Balances_Stream_Cursor_Value_Input = { - amount?: InputMaybe; - delegator_address?: InputMaybe; - last_transaction_version?: InputMaybe; - pool_address?: InputMaybe; - pool_type?: InputMaybe; - table_handle?: InputMaybe; -}; - -/** aggregate sum on columns */ -export type Current_Delegator_Balances_Sum_Fields = { - __typename?: 'current_delegator_balances_sum_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** aggregate var_pop on columns */ -export type Current_Delegator_Balances_Var_Pop_Fields = { - __typename?: 'current_delegator_balances_var_pop_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** aggregate var_samp on columns */ -export type Current_Delegator_Balances_Var_Samp_Fields = { - __typename?: 'current_delegator_balances_var_samp_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** aggregate variance on columns */ -export type Current_Delegator_Balances_Variance_Fields = { - __typename?: 'current_delegator_balances_variance_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; -}; - -/** columns and relationships of "current_staking_pool_voter" */ -export type Current_Staking_Pool_Voter = { - __typename?: 'current_staking_pool_voter'; - last_transaction_version: Scalars['bigint']; - staking_pool_address: Scalars['String']; - voter_address: Scalars['String']; -}; - -/** Boolean expression to filter rows from the table "current_staking_pool_voter". All fields are combined with a logical 'AND'. */ -export type Current_Staking_Pool_Voter_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - last_transaction_version?: InputMaybe; - staking_pool_address?: InputMaybe; - voter_address?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_staking_pool_voter". */ -export type Current_Staking_Pool_Voter_Order_By = { - last_transaction_version?: InputMaybe; - staking_pool_address?: InputMaybe; - voter_address?: InputMaybe; -}; - -/** select columns of table "current_staking_pool_voter" */ -export enum Current_Staking_Pool_Voter_Select_Column { - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - StakingPoolAddress = 'staking_pool_address', - /** column name */ - VoterAddress = 'voter_address' -} - -/** Streaming cursor of the table "current_staking_pool_voter" */ -export type Current_Staking_Pool_Voter_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Staking_Pool_Voter_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Staking_Pool_Voter_Stream_Cursor_Value_Input = { - last_transaction_version?: InputMaybe; - staking_pool_address?: InputMaybe; - voter_address?: InputMaybe; -}; - -/** columns and relationships of "current_table_items" */ -export type Current_Table_Items = { - __typename?: 'current_table_items'; - decoded_key: Scalars['jsonb']; - decoded_value?: Maybe; - is_deleted: Scalars['Boolean']; - key: Scalars['String']; - key_hash: Scalars['String']; - last_transaction_version: Scalars['bigint']; - table_handle: Scalars['String']; -}; - - -/** columns and relationships of "current_table_items" */ -export type Current_Table_ItemsDecoded_KeyArgs = { - path?: InputMaybe; -}; - - -/** columns and relationships of "current_table_items" */ -export type Current_Table_ItemsDecoded_ValueArgs = { - path?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "current_table_items". All fields are combined with a logical 'AND'. */ -export type Current_Table_Items_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - decoded_key?: InputMaybe; - decoded_value?: InputMaybe; - is_deleted?: InputMaybe; - key?: InputMaybe; - key_hash?: InputMaybe; - last_transaction_version?: InputMaybe; - table_handle?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_table_items". */ -export type Current_Table_Items_Order_By = { - decoded_key?: InputMaybe; - decoded_value?: InputMaybe; - is_deleted?: InputMaybe; - key?: InputMaybe; - key_hash?: InputMaybe; - last_transaction_version?: InputMaybe; - table_handle?: InputMaybe; -}; - -/** select columns of table "current_table_items" */ -export enum Current_Table_Items_Select_Column { - /** column name */ - DecodedKey = 'decoded_key', - /** column name */ - DecodedValue = 'decoded_value', - /** column name */ - IsDeleted = 'is_deleted', - /** column name */ - Key = 'key', - /** column name */ - KeyHash = 'key_hash', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - TableHandle = 'table_handle' -} - -/** Streaming cursor of the table "current_table_items" */ -export type Current_Table_Items_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Table_Items_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Table_Items_Stream_Cursor_Value_Input = { - decoded_key?: InputMaybe; - decoded_value?: InputMaybe; - is_deleted?: InputMaybe; - key?: InputMaybe; - key_hash?: InputMaybe; - last_transaction_version?: InputMaybe; - table_handle?: InputMaybe; -}; - -/** columns and relationships of "current_token_datas" */ -export type Current_Token_Datas = { - __typename?: 'current_token_datas'; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - /** An object relationship */ - current_collection_data?: Maybe; - default_properties: Scalars['jsonb']; - description: Scalars['String']; - description_mutable: Scalars['Boolean']; - largest_property_version: Scalars['numeric']; - last_transaction_timestamp: Scalars['timestamp']; - last_transaction_version: Scalars['bigint']; - maximum: Scalars['numeric']; - maximum_mutable: Scalars['Boolean']; - metadata_uri: Scalars['String']; - name: Scalars['String']; - payee_address: Scalars['String']; - properties_mutable: Scalars['Boolean']; - royalty_mutable: Scalars['Boolean']; - royalty_points_denominator: Scalars['numeric']; - royalty_points_numerator: Scalars['numeric']; - supply: Scalars['numeric']; - token_data_id_hash: Scalars['String']; - uri_mutable: Scalars['Boolean']; -}; - - -/** columns and relationships of "current_token_datas" */ -export type Current_Token_DatasDefault_PropertiesArgs = { - path?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "current_token_datas". All fields are combined with a logical 'AND'. */ -export type Current_Token_Datas_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_collection_data?: InputMaybe; - default_properties?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - largest_property_version?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - name?: InputMaybe; - payee_address?: InputMaybe; - properties_mutable?: InputMaybe; - royalty_mutable?: InputMaybe; - royalty_points_denominator?: InputMaybe; - royalty_points_numerator?: InputMaybe; - supply?: InputMaybe; - token_data_id_hash?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_token_datas". */ -export type Current_Token_Datas_Order_By = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_collection_data?: InputMaybe; - default_properties?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - largest_property_version?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - name?: InputMaybe; - payee_address?: InputMaybe; - properties_mutable?: InputMaybe; - royalty_mutable?: InputMaybe; - royalty_points_denominator?: InputMaybe; - royalty_points_numerator?: InputMaybe; - supply?: InputMaybe; - token_data_id_hash?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** select columns of table "current_token_datas" */ -export enum Current_Token_Datas_Select_Column { - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - DefaultProperties = 'default_properties', - /** column name */ - Description = 'description', - /** column name */ - DescriptionMutable = 'description_mutable', - /** column name */ - LargestPropertyVersion = 'largest_property_version', - /** column name */ - LastTransactionTimestamp = 'last_transaction_timestamp', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - Maximum = 'maximum', - /** column name */ - MaximumMutable = 'maximum_mutable', - /** column name */ - MetadataUri = 'metadata_uri', - /** column name */ - Name = 'name', - /** column name */ - PayeeAddress = 'payee_address', - /** column name */ - PropertiesMutable = 'properties_mutable', - /** column name */ - RoyaltyMutable = 'royalty_mutable', - /** column name */ - RoyaltyPointsDenominator = 'royalty_points_denominator', - /** column name */ - RoyaltyPointsNumerator = 'royalty_points_numerator', - /** column name */ - Supply = 'supply', - /** column name */ - TokenDataIdHash = 'token_data_id_hash', - /** column name */ - UriMutable = 'uri_mutable' -} - -/** Streaming cursor of the table "current_token_datas" */ -export type Current_Token_Datas_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Token_Datas_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Token_Datas_Stream_Cursor_Value_Input = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - default_properties?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - largest_property_version?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - name?: InputMaybe; - payee_address?: InputMaybe; - properties_mutable?: InputMaybe; - royalty_mutable?: InputMaybe; - royalty_points_denominator?: InputMaybe; - royalty_points_numerator?: InputMaybe; - supply?: InputMaybe; - token_data_id_hash?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** columns and relationships of "current_token_ownerships" */ -export type Current_Token_Ownerships = { - __typename?: 'current_token_ownerships'; - amount: Scalars['numeric']; - /** An object relationship */ - aptos_name?: Maybe; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - /** An object relationship */ - current_collection_data?: Maybe; - /** An object relationship */ - current_token_data?: Maybe; - last_transaction_timestamp: Scalars['timestamp']; - last_transaction_version: Scalars['bigint']; - name: Scalars['String']; - owner_address: Scalars['String']; - property_version: Scalars['numeric']; - table_type: Scalars['String']; - token_data_id_hash: Scalars['String']; - token_properties: Scalars['jsonb']; -}; - - -/** columns and relationships of "current_token_ownerships" */ -export type Current_Token_OwnershipsToken_PropertiesArgs = { - path?: InputMaybe; -}; - -/** aggregated selection of "current_token_ownerships" */ -export type Current_Token_Ownerships_Aggregate = { - __typename?: 'current_token_ownerships_aggregate'; - aggregate?: Maybe; - nodes: Array; -}; - -/** aggregate fields of "current_token_ownerships" */ -export type Current_Token_Ownerships_Aggregate_Fields = { - __typename?: 'current_token_ownerships_aggregate_fields'; - avg?: Maybe; - count: Scalars['Int']; - max?: Maybe; - min?: Maybe; - stddev?: Maybe; - stddev_pop?: Maybe; - stddev_samp?: Maybe; - sum?: Maybe; - var_pop?: Maybe; - var_samp?: Maybe; - variance?: Maybe; -}; - - -/** aggregate fields of "current_token_ownerships" */ -export type Current_Token_Ownerships_Aggregate_FieldsCountArgs = { - columns?: InputMaybe>; - distinct?: InputMaybe; -}; - -/** order by aggregate values of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Aggregate_Order_By = { - avg?: InputMaybe; - count?: InputMaybe; - max?: InputMaybe; - min?: InputMaybe; - stddev?: InputMaybe; - stddev_pop?: InputMaybe; - stddev_samp?: InputMaybe; - sum?: InputMaybe; - var_pop?: InputMaybe; - var_samp?: InputMaybe; - variance?: InputMaybe; -}; - -/** aggregate avg on columns */ -export type Current_Token_Ownerships_Avg_Fields = { - __typename?: 'current_token_ownerships_avg_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by avg() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Avg_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "current_token_ownerships". All fields are combined with a logical 'AND'. */ -export type Current_Token_Ownerships_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - amount?: InputMaybe; - aptos_name?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_collection_data?: InputMaybe; - current_token_data?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; - token_properties?: InputMaybe; -}; - -/** aggregate max on columns */ -export type Current_Token_Ownerships_Max_Fields = { - __typename?: 'current_token_ownerships_max_fields'; - amount?: Maybe; - collection_data_id_hash?: Maybe; - collection_name?: Maybe; - creator_address?: Maybe; - last_transaction_timestamp?: Maybe; - last_transaction_version?: Maybe; - name?: Maybe; - owner_address?: Maybe; - property_version?: Maybe; - table_type?: Maybe; - token_data_id_hash?: Maybe; -}; - -/** order by max() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Max_Order_By = { - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; -}; - -/** aggregate min on columns */ -export type Current_Token_Ownerships_Min_Fields = { - __typename?: 'current_token_ownerships_min_fields'; - amount?: Maybe; - collection_data_id_hash?: Maybe; - collection_name?: Maybe; - creator_address?: Maybe; - last_transaction_timestamp?: Maybe; - last_transaction_version?: Maybe; - name?: Maybe; - owner_address?: Maybe; - property_version?: Maybe; - table_type?: Maybe; - token_data_id_hash?: Maybe; -}; - -/** order by min() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Min_Order_By = { - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_token_ownerships". */ -export type Current_Token_Ownerships_Order_By = { - amount?: InputMaybe; - aptos_name?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_collection_data?: InputMaybe; - current_token_data?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; - token_properties?: InputMaybe; -}; - -/** select columns of table "current_token_ownerships" */ -export enum Current_Token_Ownerships_Select_Column { - /** column name */ - Amount = 'amount', - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - LastTransactionTimestamp = 'last_transaction_timestamp', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - Name = 'name', - /** column name */ - OwnerAddress = 'owner_address', - /** column name */ - PropertyVersion = 'property_version', - /** column name */ - TableType = 'table_type', - /** column name */ - TokenDataIdHash = 'token_data_id_hash', - /** column name */ - TokenProperties = 'token_properties' -} - -/** aggregate stddev on columns */ -export type Current_Token_Ownerships_Stddev_Fields = { - __typename?: 'current_token_ownerships_stddev_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by stddev() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Stddev_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** aggregate stddev_pop on columns */ -export type Current_Token_Ownerships_Stddev_Pop_Fields = { - __typename?: 'current_token_ownerships_stddev_pop_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by stddev_pop() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Stddev_Pop_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** aggregate stddev_samp on columns */ -export type Current_Token_Ownerships_Stddev_Samp_Fields = { - __typename?: 'current_token_ownerships_stddev_samp_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by stddev_samp() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Stddev_Samp_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** Streaming cursor of the table "current_token_ownerships" */ -export type Current_Token_Ownerships_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Token_Ownerships_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Token_Ownerships_Stream_Cursor_Value_Input = { - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; - token_properties?: InputMaybe; -}; - -/** aggregate sum on columns */ -export type Current_Token_Ownerships_Sum_Fields = { - __typename?: 'current_token_ownerships_sum_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by sum() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Sum_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** aggregate var_pop on columns */ -export type Current_Token_Ownerships_Var_Pop_Fields = { - __typename?: 'current_token_ownerships_var_pop_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by var_pop() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Var_Pop_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** aggregate var_samp on columns */ -export type Current_Token_Ownerships_Var_Samp_Fields = { - __typename?: 'current_token_ownerships_var_samp_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by var_samp() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Var_Samp_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** aggregate variance on columns */ -export type Current_Token_Ownerships_Variance_Fields = { - __typename?: 'current_token_ownerships_variance_fields'; - amount?: Maybe; - last_transaction_version?: Maybe; - property_version?: Maybe; -}; - -/** order by variance() on columns of table "current_token_ownerships" */ -export type Current_Token_Ownerships_Variance_Order_By = { - amount?: InputMaybe; - last_transaction_version?: InputMaybe; - property_version?: InputMaybe; -}; - -/** columns and relationships of "current_token_pending_claims" */ -export type Current_Token_Pending_Claims = { - __typename?: 'current_token_pending_claims'; - amount: Scalars['numeric']; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - /** An object relationship */ - current_collection_data?: Maybe; - /** An object relationship */ - current_token_data?: Maybe; - from_address: Scalars['String']; - last_transaction_timestamp: Scalars['timestamp']; - last_transaction_version: Scalars['bigint']; - name: Scalars['String']; - property_version: Scalars['numeric']; - table_handle: Scalars['String']; - to_address: Scalars['String']; - /** An object relationship */ - token?: Maybe; - token_data_id_hash: Scalars['String']; -}; - -/** Boolean expression to filter rows from the table "current_token_pending_claims". All fields are combined with a logical 'AND'. */ -export type Current_Token_Pending_Claims_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_collection_data?: InputMaybe; - current_token_data?: InputMaybe; - from_address?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - table_handle?: InputMaybe; - to_address?: InputMaybe; - token?: InputMaybe; - token_data_id_hash?: InputMaybe; -}; - -/** Ordering options when selecting data from "current_token_pending_claims". */ -export type Current_Token_Pending_Claims_Order_By = { - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_collection_data?: InputMaybe; - current_token_data?: InputMaybe; - from_address?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - table_handle?: InputMaybe; - to_address?: InputMaybe; - token?: InputMaybe; - token_data_id_hash?: InputMaybe; -}; - -/** select columns of table "current_token_pending_claims" */ -export enum Current_Token_Pending_Claims_Select_Column { - /** column name */ - Amount = 'amount', - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - FromAddress = 'from_address', - /** column name */ - LastTransactionTimestamp = 'last_transaction_timestamp', - /** column name */ - LastTransactionVersion = 'last_transaction_version', - /** column name */ - Name = 'name', - /** column name */ - PropertyVersion = 'property_version', - /** column name */ - TableHandle = 'table_handle', - /** column name */ - ToAddress = 'to_address', - /** column name */ - TokenDataIdHash = 'token_data_id_hash' -} - -/** Streaming cursor of the table "current_token_pending_claims" */ -export type Current_Token_Pending_Claims_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Current_Token_Pending_Claims_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Current_Token_Pending_Claims_Stream_Cursor_Value_Input = { - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - from_address?: InputMaybe; - last_transaction_timestamp?: InputMaybe; - last_transaction_version?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - table_handle?: InputMaybe; - to_address?: InputMaybe; - token_data_id_hash?: InputMaybe; -}; - -/** ordering argument of a cursor */ -export enum Cursor_Ordering { - /** ascending ordering of the cursor */ - Asc = 'ASC', - /** descending ordering of the cursor */ - Desc = 'DESC' -} - -/** columns and relationships of "delegated_staking_activities" */ -export type Delegated_Staking_Activities = { - __typename?: 'delegated_staking_activities'; - amount: Scalars['numeric']; - delegator_address: Scalars['String']; - event_index: Scalars['bigint']; - event_type: Scalars['String']; - pool_address: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "delegated_staking_activities". All fields are combined with a logical 'AND'. */ -export type Delegated_Staking_Activities_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - amount?: InputMaybe; - delegator_address?: InputMaybe; - event_index?: InputMaybe; - event_type?: InputMaybe; - pool_address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Ordering options when selecting data from "delegated_staking_activities". */ -export type Delegated_Staking_Activities_Order_By = { - amount?: InputMaybe; - delegator_address?: InputMaybe; - event_index?: InputMaybe; - event_type?: InputMaybe; - pool_address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "delegated_staking_activities" */ -export enum Delegated_Staking_Activities_Select_Column { - /** column name */ - Amount = 'amount', - /** column name */ - DelegatorAddress = 'delegator_address', - /** column name */ - EventIndex = 'event_index', - /** column name */ - EventType = 'event_type', - /** column name */ - PoolAddress = 'pool_address', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** Streaming cursor of the table "delegated_staking_activities" */ -export type Delegated_Staking_Activities_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Delegated_Staking_Activities_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Delegated_Staking_Activities_Stream_Cursor_Value_Input = { - amount?: InputMaybe; - delegator_address?: InputMaybe; - event_index?: InputMaybe; - event_type?: InputMaybe; - pool_address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** columns and relationships of "events" */ -export type Events = { - __typename?: 'events'; - account_address: Scalars['String']; - creation_number: Scalars['bigint']; - data: Scalars['jsonb']; - event_index?: Maybe; - sequence_number: Scalars['bigint']; - transaction_block_height: Scalars['bigint']; - transaction_version: Scalars['bigint']; - type: Scalars['String']; -}; - - -/** columns and relationships of "events" */ -export type EventsDataArgs = { - path?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "events". All fields are combined with a logical 'AND'. */ -export type Events_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - account_address?: InputMaybe; - creation_number?: InputMaybe; - data?: InputMaybe; - event_index?: InputMaybe; - sequence_number?: InputMaybe; - transaction_block_height?: InputMaybe; - transaction_version?: InputMaybe; - type?: InputMaybe; -}; - -/** Ordering options when selecting data from "events". */ -export type Events_Order_By = { - account_address?: InputMaybe; - creation_number?: InputMaybe; - data?: InputMaybe; - event_index?: InputMaybe; - sequence_number?: InputMaybe; - transaction_block_height?: InputMaybe; - transaction_version?: InputMaybe; - type?: InputMaybe; -}; - -/** select columns of table "events" */ -export enum Events_Select_Column { - /** column name */ - AccountAddress = 'account_address', - /** column name */ - CreationNumber = 'creation_number', - /** column name */ - Data = 'data', - /** column name */ - EventIndex = 'event_index', - /** column name */ - SequenceNumber = 'sequence_number', - /** column name */ - TransactionBlockHeight = 'transaction_block_height', - /** column name */ - TransactionVersion = 'transaction_version', - /** column name */ - Type = 'type' -} - -/** Streaming cursor of the table "events" */ -export type Events_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Events_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Events_Stream_Cursor_Value_Input = { - account_address?: InputMaybe; - creation_number?: InputMaybe; - data?: InputMaybe; - event_index?: InputMaybe; - sequence_number?: InputMaybe; - transaction_block_height?: InputMaybe; - transaction_version?: InputMaybe; - type?: InputMaybe; -}; - -/** columns and relationships of "indexer_status" */ -export type Indexer_Status = { - __typename?: 'indexer_status'; - db: Scalars['String']; - is_indexer_up: Scalars['Boolean']; -}; - -/** Boolean expression to filter rows from the table "indexer_status". All fields are combined with a logical 'AND'. */ -export type Indexer_Status_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - db?: InputMaybe; - is_indexer_up?: InputMaybe; -}; - -/** Ordering options when selecting data from "indexer_status". */ -export type Indexer_Status_Order_By = { - db?: InputMaybe; - is_indexer_up?: InputMaybe; -}; - -/** select columns of table "indexer_status" */ -export enum Indexer_Status_Select_Column { - /** column name */ - Db = 'db', - /** column name */ - IsIndexerUp = 'is_indexer_up' -} - -/** Streaming cursor of the table "indexer_status" */ -export type Indexer_Status_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Indexer_Status_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Indexer_Status_Stream_Cursor_Value_Input = { - db?: InputMaybe; - is_indexer_up?: InputMaybe; -}; - -export type Jsonb_Cast_Exp = { - String?: InputMaybe; -}; - -/** Boolean expression to compare columns of type "jsonb". All fields are combined with logical 'AND'. */ -export type Jsonb_Comparison_Exp = { - _cast?: InputMaybe; - /** is the column contained in the given json value */ - _contained_in?: InputMaybe; - /** does the column contain the given json value at the top level */ - _contains?: InputMaybe; - _eq?: InputMaybe; - _gt?: InputMaybe; - _gte?: InputMaybe; - /** does the string exist as a top-level key in the column */ - _has_key?: InputMaybe; - /** do all of these strings exist as top-level keys in the column */ - _has_keys_all?: InputMaybe>; - /** do any of these strings exist as top-level keys in the column */ - _has_keys_any?: InputMaybe>; - _in?: InputMaybe>; - _is_null?: InputMaybe; - _lt?: InputMaybe; - _lte?: InputMaybe; - _neq?: InputMaybe; - _nin?: InputMaybe>; -}; - -/** columns and relationships of "ledger_infos" */ -export type Ledger_Infos = { - __typename?: 'ledger_infos'; - chain_id: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "ledger_infos". All fields are combined with a logical 'AND'. */ -export type Ledger_Infos_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - chain_id?: InputMaybe; -}; - -/** Ordering options when selecting data from "ledger_infos". */ -export type Ledger_Infos_Order_By = { - chain_id?: InputMaybe; -}; - -/** select columns of table "ledger_infos" */ -export enum Ledger_Infos_Select_Column { - /** column name */ - ChainId = 'chain_id' -} - -/** Streaming cursor of the table "ledger_infos" */ -export type Ledger_Infos_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Ledger_Infos_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Ledger_Infos_Stream_Cursor_Value_Input = { - chain_id?: InputMaybe; -}; - -/** columns and relationships of "move_resources" */ -export type Move_Resources = { - __typename?: 'move_resources'; - address: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - -/** aggregated selection of "move_resources" */ -export type Move_Resources_Aggregate = { - __typename?: 'move_resources_aggregate'; - aggregate?: Maybe; - nodes: Array; -}; - -/** aggregate fields of "move_resources" */ -export type Move_Resources_Aggregate_Fields = { - __typename?: 'move_resources_aggregate_fields'; - avg?: Maybe; - count: Scalars['Int']; - max?: Maybe; - min?: Maybe; - stddev?: Maybe; - stddev_pop?: Maybe; - stddev_samp?: Maybe; - sum?: Maybe; - var_pop?: Maybe; - var_samp?: Maybe; - variance?: Maybe; -}; - - -/** aggregate fields of "move_resources" */ -export type Move_Resources_Aggregate_FieldsCountArgs = { - columns?: InputMaybe>; - distinct?: InputMaybe; -}; - -/** aggregate avg on columns */ -export type Move_Resources_Avg_Fields = { - __typename?: 'move_resources_avg_fields'; - transaction_version?: Maybe; -}; - -/** Boolean expression to filter rows from the table "move_resources". All fields are combined with a logical 'AND'. */ -export type Move_Resources_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** aggregate max on columns */ -export type Move_Resources_Max_Fields = { - __typename?: 'move_resources_max_fields'; - address?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate min on columns */ -export type Move_Resources_Min_Fields = { - __typename?: 'move_resources_min_fields'; - address?: Maybe; - transaction_version?: Maybe; -}; - -/** Ordering options when selecting data from "move_resources". */ -export type Move_Resources_Order_By = { - address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "move_resources" */ -export enum Move_Resources_Select_Column { - /** column name */ - Address = 'address', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** aggregate stddev on columns */ -export type Move_Resources_Stddev_Fields = { - __typename?: 'move_resources_stddev_fields'; - transaction_version?: Maybe; -}; - -/** aggregate stddev_pop on columns */ -export type Move_Resources_Stddev_Pop_Fields = { - __typename?: 'move_resources_stddev_pop_fields'; - transaction_version?: Maybe; -}; - -/** aggregate stddev_samp on columns */ -export type Move_Resources_Stddev_Samp_Fields = { - __typename?: 'move_resources_stddev_samp_fields'; - transaction_version?: Maybe; -}; - -/** Streaming cursor of the table "move_resources" */ -export type Move_Resources_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Move_Resources_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Move_Resources_Stream_Cursor_Value_Input = { - address?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** aggregate sum on columns */ -export type Move_Resources_Sum_Fields = { - __typename?: 'move_resources_sum_fields'; - transaction_version?: Maybe; -}; - -/** aggregate var_pop on columns */ -export type Move_Resources_Var_Pop_Fields = { - __typename?: 'move_resources_var_pop_fields'; - transaction_version?: Maybe; -}; - -/** aggregate var_samp on columns */ -export type Move_Resources_Var_Samp_Fields = { - __typename?: 'move_resources_var_samp_fields'; - transaction_version?: Maybe; -}; - -/** aggregate variance on columns */ -export type Move_Resources_Variance_Fields = { - __typename?: 'move_resources_variance_fields'; - transaction_version?: Maybe; -}; - -/** Boolean expression to compare columns of type "numeric". All fields are combined with logical 'AND'. */ -export type Numeric_Comparison_Exp = { - _eq?: InputMaybe; - _gt?: InputMaybe; - _gte?: InputMaybe; - _in?: InputMaybe>; - _is_null?: InputMaybe; - _lt?: InputMaybe; - _lte?: InputMaybe; - _neq?: InputMaybe; - _nin?: InputMaybe>; -}; - -/** column ordering options */ -export enum Order_By { - /** in ascending order, nulls last */ - Asc = 'asc', - /** in ascending order, nulls first */ - AscNullsFirst = 'asc_nulls_first', - /** in ascending order, nulls last */ - AscNullsLast = 'asc_nulls_last', - /** in descending order, nulls first */ - Desc = 'desc', - /** in descending order, nulls first */ - DescNullsFirst = 'desc_nulls_first', - /** in descending order, nulls last */ - DescNullsLast = 'desc_nulls_last' -} - -/** columns and relationships of "processor_status" */ -export type Processor_Status = { - __typename?: 'processor_status'; - last_success_version: Scalars['bigint']; - processor: Scalars['String']; -}; - -/** Boolean expression to filter rows from the table "processor_status". All fields are combined with a logical 'AND'. */ -export type Processor_Status_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - last_success_version?: InputMaybe; - processor?: InputMaybe; -}; - -/** Ordering options when selecting data from "processor_status". */ -export type Processor_Status_Order_By = { - last_success_version?: InputMaybe; - processor?: InputMaybe; -}; - -/** select columns of table "processor_status" */ -export enum Processor_Status_Select_Column { - /** column name */ - LastSuccessVersion = 'last_success_version', - /** column name */ - Processor = 'processor' -} - -/** Streaming cursor of the table "processor_status" */ -export type Processor_Status_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Processor_Status_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Processor_Status_Stream_Cursor_Value_Input = { - last_success_version?: InputMaybe; - processor?: InputMaybe; -}; - -/** columns and relationships of "proposal_votes" */ -export type Proposal_Votes = { - __typename?: 'proposal_votes'; - num_votes: Scalars['numeric']; - proposal_id: Scalars['bigint']; - should_pass: Scalars['Boolean']; - staking_pool_address: Scalars['String']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; - voter_address: Scalars['String']; -}; - -/** aggregated selection of "proposal_votes" */ -export type Proposal_Votes_Aggregate = { - __typename?: 'proposal_votes_aggregate'; - aggregate?: Maybe; - nodes: Array; -}; - -/** aggregate fields of "proposal_votes" */ -export type Proposal_Votes_Aggregate_Fields = { - __typename?: 'proposal_votes_aggregate_fields'; - avg?: Maybe; - count: Scalars['Int']; - max?: Maybe; - min?: Maybe; - stddev?: Maybe; - stddev_pop?: Maybe; - stddev_samp?: Maybe; - sum?: Maybe; - var_pop?: Maybe; - var_samp?: Maybe; - variance?: Maybe; -}; - - -/** aggregate fields of "proposal_votes" */ -export type Proposal_Votes_Aggregate_FieldsCountArgs = { - columns?: InputMaybe>; - distinct?: InputMaybe; -}; - -/** aggregate avg on columns */ -export type Proposal_Votes_Avg_Fields = { - __typename?: 'proposal_votes_avg_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -/** Boolean expression to filter rows from the table "proposal_votes". All fields are combined with a logical 'AND'. */ -export type Proposal_Votes_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - num_votes?: InputMaybe; - proposal_id?: InputMaybe; - should_pass?: InputMaybe; - staking_pool_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - voter_address?: InputMaybe; -}; - -/** aggregate max on columns */ -export type Proposal_Votes_Max_Fields = { - __typename?: 'proposal_votes_max_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - staking_pool_address?: Maybe; - transaction_timestamp?: Maybe; - transaction_version?: Maybe; - voter_address?: Maybe; -}; - -/** aggregate min on columns */ -export type Proposal_Votes_Min_Fields = { - __typename?: 'proposal_votes_min_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - staking_pool_address?: Maybe; - transaction_timestamp?: Maybe; - transaction_version?: Maybe; - voter_address?: Maybe; -}; - -/** Ordering options when selecting data from "proposal_votes". */ -export type Proposal_Votes_Order_By = { - num_votes?: InputMaybe; - proposal_id?: InputMaybe; - should_pass?: InputMaybe; - staking_pool_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - voter_address?: InputMaybe; -}; - -/** select columns of table "proposal_votes" */ -export enum Proposal_Votes_Select_Column { - /** column name */ - NumVotes = 'num_votes', - /** column name */ - ProposalId = 'proposal_id', - /** column name */ - ShouldPass = 'should_pass', - /** column name */ - StakingPoolAddress = 'staking_pool_address', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version', - /** column name */ - VoterAddress = 'voter_address' -} - -/** aggregate stddev on columns */ -export type Proposal_Votes_Stddev_Fields = { - __typename?: 'proposal_votes_stddev_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate stddev_pop on columns */ -export type Proposal_Votes_Stddev_Pop_Fields = { - __typename?: 'proposal_votes_stddev_pop_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate stddev_samp on columns */ -export type Proposal_Votes_Stddev_Samp_Fields = { - __typename?: 'proposal_votes_stddev_samp_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -/** Streaming cursor of the table "proposal_votes" */ -export type Proposal_Votes_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Proposal_Votes_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Proposal_Votes_Stream_Cursor_Value_Input = { - num_votes?: InputMaybe; - proposal_id?: InputMaybe; - should_pass?: InputMaybe; - staking_pool_address?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - voter_address?: InputMaybe; -}; - -/** aggregate sum on columns */ -export type Proposal_Votes_Sum_Fields = { - __typename?: 'proposal_votes_sum_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate var_pop on columns */ -export type Proposal_Votes_Var_Pop_Fields = { - __typename?: 'proposal_votes_var_pop_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate var_samp on columns */ -export type Proposal_Votes_Var_Samp_Fields = { - __typename?: 'proposal_votes_var_samp_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate variance on columns */ -export type Proposal_Votes_Variance_Fields = { - __typename?: 'proposal_votes_variance_fields'; - num_votes?: Maybe; - proposal_id?: Maybe; - transaction_version?: Maybe; -}; - -export type Query_Root = { - __typename?: 'query_root'; - /** fetch data from the table: "address_version_from_events" */ - address_version_from_events: Array; - coin_activities: Array; - /** fetch data from the table: "coin_activities" using primary key columns */ - coin_activities_by_pk?: Maybe; - /** fetch data from the table: "coin_balances" */ - coin_balances: Array; - /** fetch data from the table: "coin_balances" using primary key columns */ - coin_balances_by_pk?: Maybe; - /** fetch data from the table: "coin_infos" */ - coin_infos: Array; - /** fetch data from the table: "coin_infos" using primary key columns */ - coin_infos_by_pk?: Maybe; - /** fetch data from the table: "coin_supply" */ - coin_supply: Array; - /** fetch data from the table: "coin_supply" using primary key columns */ - coin_supply_by_pk?: Maybe; - /** fetch data from the table: "collection_datas" */ - collection_datas: Array; - /** fetch data from the table: "collection_datas" using primary key columns */ - collection_datas_by_pk?: Maybe; - /** fetch data from the table: "current_ans_lookup" */ - current_ans_lookup: Array; - /** fetch data from the table: "current_ans_lookup" using primary key columns */ - current_ans_lookup_by_pk?: Maybe; - /** fetch data from the table: "current_coin_balances" */ - current_coin_balances: Array; - /** fetch data from the table: "current_coin_balances" using primary key columns */ - current_coin_balances_by_pk?: Maybe; - /** fetch data from the table: "current_collection_datas" */ - current_collection_datas: Array; - /** fetch data from the table: "current_collection_datas" using primary key columns */ - current_collection_datas_by_pk?: Maybe; - /** fetch data from the table: "current_collection_ownership_view" */ - current_collection_ownership_view: Array; - /** fetch data from the table: "current_delegator_balances" */ - current_delegator_balances: Array; - /** fetch aggregated fields from the table: "current_delegator_balances" */ - current_delegator_balances_aggregate: Current_Delegator_Balances_Aggregate; - /** fetch data from the table: "current_delegator_balances" using primary key columns */ - current_delegator_balances_by_pk?: Maybe; - /** fetch data from the table: "current_staking_pool_voter" */ - current_staking_pool_voter: Array; - /** fetch data from the table: "current_staking_pool_voter" using primary key columns */ - current_staking_pool_voter_by_pk?: Maybe; - /** fetch data from the table: "current_table_items" */ - current_table_items: Array; - /** fetch data from the table: "current_table_items" using primary key columns */ - current_table_items_by_pk?: Maybe; - /** fetch data from the table: "current_token_datas" */ - current_token_datas: Array; - /** fetch data from the table: "current_token_datas" using primary key columns */ - current_token_datas_by_pk?: Maybe; - /** fetch data from the table: "current_token_ownerships" */ - current_token_ownerships: Array; - /** fetch aggregated fields from the table: "current_token_ownerships" */ - current_token_ownerships_aggregate: Current_Token_Ownerships_Aggregate; - /** fetch data from the table: "current_token_ownerships" using primary key columns */ - current_token_ownerships_by_pk?: Maybe; - /** fetch data from the table: "current_token_pending_claims" */ - current_token_pending_claims: Array; - /** fetch data from the table: "current_token_pending_claims" using primary key columns */ - current_token_pending_claims_by_pk?: Maybe; - /** fetch data from the table: "delegated_staking_activities" */ - delegated_staking_activities: Array; - /** fetch data from the table: "delegated_staking_activities" using primary key columns */ - delegated_staking_activities_by_pk?: Maybe; - /** fetch data from the table: "events" */ - events: Array; - /** fetch data from the table: "events" using primary key columns */ - events_by_pk?: Maybe; - /** fetch data from the table: "indexer_status" */ - indexer_status: Array; - /** fetch data from the table: "indexer_status" using primary key columns */ - indexer_status_by_pk?: Maybe; - /** fetch data from the table: "ledger_infos" */ - ledger_infos: Array; - /** fetch data from the table: "ledger_infos" using primary key columns */ - ledger_infos_by_pk?: Maybe; - /** fetch data from the table: "move_resources" */ - move_resources: Array; - /** fetch aggregated fields from the table: "move_resources" */ - move_resources_aggregate: Move_Resources_Aggregate; - /** fetch data from the table: "processor_status" */ - processor_status: Array; - /** fetch data from the table: "processor_status" using primary key columns */ - processor_status_by_pk?: Maybe; - /** fetch data from the table: "proposal_votes" */ - proposal_votes: Array; - /** fetch aggregated fields from the table: "proposal_votes" */ - proposal_votes_aggregate: Proposal_Votes_Aggregate; - /** fetch data from the table: "proposal_votes" using primary key columns */ - proposal_votes_by_pk?: Maybe; - /** fetch data from the table: "table_items" */ - table_items: Array; - /** fetch data from the table: "table_items" using primary key columns */ - table_items_by_pk?: Maybe; - /** fetch data from the table: "table_metadatas" */ - table_metadatas: Array; - /** fetch data from the table: "table_metadatas" using primary key columns */ - table_metadatas_by_pk?: Maybe; - token_activities: Array; - token_activities_aggregate: Token_Activities_Aggregate; - /** fetch data from the table: "token_activities" using primary key columns */ - token_activities_by_pk?: Maybe; - /** fetch data from the table: "token_datas" */ - token_datas: Array; - /** fetch data from the table: "token_datas" using primary key columns */ - token_datas_by_pk?: Maybe; - /** fetch data from the table: "token_ownerships" */ - token_ownerships: Array; - /** fetch data from the table: "token_ownerships" using primary key columns */ - token_ownerships_by_pk?: Maybe; - /** fetch data from the table: "tokens" */ - tokens: Array; - /** fetch data from the table: "tokens" using primary key columns */ - tokens_by_pk?: Maybe; - /** fetch data from the table: "user_transactions" */ - user_transactions: Array; - /** fetch data from the table: "user_transactions" using primary key columns */ - user_transactions_by_pk?: Maybe; -}; - - -export type Query_RootAddress_Version_From_EventsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCoin_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCoin_Activities_By_PkArgs = { - event_account_address: Scalars['String']; - event_creation_number: Scalars['bigint']; - event_sequence_number: Scalars['bigint']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootCoin_BalancesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCoin_Balances_By_PkArgs = { - coin_type_hash: Scalars['String']; - owner_address: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootCoin_InfosArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCoin_Infos_By_PkArgs = { - coin_type_hash: Scalars['String']; -}; - - -export type Query_RootCoin_SupplyArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCoin_Supply_By_PkArgs = { - coin_type_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootCollection_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCollection_Datas_By_PkArgs = { - collection_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootCurrent_Ans_LookupArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Ans_Lookup_By_PkArgs = { - domain: Scalars['String']; - subdomain: Scalars['String']; -}; - - -export type Query_RootCurrent_Coin_BalancesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Coin_Balances_By_PkArgs = { - coin_type_hash: Scalars['String']; - owner_address: Scalars['String']; -}; - - -export type Query_RootCurrent_Collection_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Collection_Datas_By_PkArgs = { - collection_data_id_hash: Scalars['String']; -}; - - -export type Query_RootCurrent_Collection_Ownership_ViewArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Delegator_BalancesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Delegator_Balances_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Delegator_Balances_By_PkArgs = { - delegator_address: Scalars['String']; - pool_address: Scalars['String']; - pool_type: Scalars['String']; -}; - - -export type Query_RootCurrent_Staking_Pool_VoterArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Staking_Pool_Voter_By_PkArgs = { - staking_pool_address: Scalars['String']; -}; - - -export type Query_RootCurrent_Table_ItemsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Table_Items_By_PkArgs = { - key_hash: Scalars['String']; - table_handle: Scalars['String']; -}; - - -export type Query_RootCurrent_Token_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Token_Datas_By_PkArgs = { - token_data_id_hash: Scalars['String']; -}; - - -export type Query_RootCurrent_Token_OwnershipsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Token_Ownerships_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Token_Ownerships_By_PkArgs = { - owner_address: Scalars['String']; - property_version: Scalars['numeric']; - token_data_id_hash: Scalars['String']; -}; - - -export type Query_RootCurrent_Token_Pending_ClaimsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootCurrent_Token_Pending_Claims_By_PkArgs = { - from_address: Scalars['String']; - property_version: Scalars['numeric']; - to_address: Scalars['String']; - token_data_id_hash: Scalars['String']; -}; - - -export type Query_RootDelegated_Staking_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootDelegated_Staking_Activities_By_PkArgs = { - event_index: Scalars['bigint']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootEventsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootEvents_By_PkArgs = { - account_address: Scalars['String']; - creation_number: Scalars['bigint']; - sequence_number: Scalars['bigint']; -}; - - -export type Query_RootIndexer_StatusArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootIndexer_Status_By_PkArgs = { - db: Scalars['String']; -}; - - -export type Query_RootLedger_InfosArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootLedger_Infos_By_PkArgs = { - chain_id: Scalars['bigint']; -}; - - -export type Query_RootMove_ResourcesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootMove_Resources_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootProcessor_StatusArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootProcessor_Status_By_PkArgs = { - processor: Scalars['String']; -}; - - -export type Query_RootProposal_VotesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootProposal_Votes_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootProposal_Votes_By_PkArgs = { - proposal_id: Scalars['bigint']; - transaction_version: Scalars['bigint']; - voter_address: Scalars['String']; -}; - - -export type Query_RootTable_ItemsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootTable_Items_By_PkArgs = { - transaction_version: Scalars['bigint']; - write_set_change_index: Scalars['bigint']; -}; - - -export type Query_RootTable_MetadatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootTable_Metadatas_By_PkArgs = { - handle: Scalars['String']; -}; - - -export type Query_RootToken_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootToken_Activities_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootToken_Activities_By_PkArgs = { - event_account_address: Scalars['String']; - event_creation_number: Scalars['bigint']; - event_sequence_number: Scalars['bigint']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootToken_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootToken_Datas_By_PkArgs = { - token_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootToken_OwnershipsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootToken_Ownerships_By_PkArgs = { - property_version: Scalars['numeric']; - table_handle: Scalars['String']; - token_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootTokensArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootTokens_By_PkArgs = { - property_version: Scalars['numeric']; - token_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Query_RootUser_TransactionsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Query_RootUser_Transactions_By_PkArgs = { - version: Scalars['bigint']; -}; - -export type Subscription_Root = { - __typename?: 'subscription_root'; - /** fetch data from the table: "address_version_from_events" */ - address_version_from_events: Array; - /** fetch data from the table in a streaming manner : "address_version_from_events" */ - address_version_from_events_stream: Array; - coin_activities: Array; - /** fetch data from the table: "coin_activities" using primary key columns */ - coin_activities_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "coin_activities" */ - coin_activities_stream: Array; - /** fetch data from the table: "coin_balances" */ - coin_balances: Array; - /** fetch data from the table: "coin_balances" using primary key columns */ - coin_balances_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "coin_balances" */ - coin_balances_stream: Array; - /** fetch data from the table: "coin_infos" */ - coin_infos: Array; - /** fetch data from the table: "coin_infos" using primary key columns */ - coin_infos_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "coin_infos" */ - coin_infos_stream: Array; - /** fetch data from the table: "coin_supply" */ - coin_supply: Array; - /** fetch data from the table: "coin_supply" using primary key columns */ - coin_supply_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "coin_supply" */ - coin_supply_stream: Array; - /** fetch data from the table: "collection_datas" */ - collection_datas: Array; - /** fetch data from the table: "collection_datas" using primary key columns */ - collection_datas_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "collection_datas" */ - collection_datas_stream: Array; - /** fetch data from the table: "current_ans_lookup" */ - current_ans_lookup: Array; - /** fetch data from the table: "current_ans_lookup" using primary key columns */ - current_ans_lookup_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_ans_lookup" */ - current_ans_lookup_stream: Array; - /** fetch data from the table: "current_coin_balances" */ - current_coin_balances: Array; - /** fetch data from the table: "current_coin_balances" using primary key columns */ - current_coin_balances_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_coin_balances" */ - current_coin_balances_stream: Array; - /** fetch data from the table: "current_collection_datas" */ - current_collection_datas: Array; - /** fetch data from the table: "current_collection_datas" using primary key columns */ - current_collection_datas_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_collection_datas" */ - current_collection_datas_stream: Array; - /** fetch data from the table: "current_collection_ownership_view" */ - current_collection_ownership_view: Array; - /** fetch data from the table in a streaming manner : "current_collection_ownership_view" */ - current_collection_ownership_view_stream: Array; - /** fetch data from the table: "current_delegator_balances" */ - current_delegator_balances: Array; - /** fetch aggregated fields from the table: "current_delegator_balances" */ - current_delegator_balances_aggregate: Current_Delegator_Balances_Aggregate; - /** fetch data from the table: "current_delegator_balances" using primary key columns */ - current_delegator_balances_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_delegator_balances" */ - current_delegator_balances_stream: Array; - /** fetch data from the table: "current_staking_pool_voter" */ - current_staking_pool_voter: Array; - /** fetch data from the table: "current_staking_pool_voter" using primary key columns */ - current_staking_pool_voter_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_staking_pool_voter" */ - current_staking_pool_voter_stream: Array; - /** fetch data from the table: "current_table_items" */ - current_table_items: Array; - /** fetch data from the table: "current_table_items" using primary key columns */ - current_table_items_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_table_items" */ - current_table_items_stream: Array; - /** fetch data from the table: "current_token_datas" */ - current_token_datas: Array; - /** fetch data from the table: "current_token_datas" using primary key columns */ - current_token_datas_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_token_datas" */ - current_token_datas_stream: Array; - /** fetch data from the table: "current_token_ownerships" */ - current_token_ownerships: Array; - /** fetch aggregated fields from the table: "current_token_ownerships" */ - current_token_ownerships_aggregate: Current_Token_Ownerships_Aggregate; - /** fetch data from the table: "current_token_ownerships" using primary key columns */ - current_token_ownerships_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_token_ownerships" */ - current_token_ownerships_stream: Array; - /** fetch data from the table: "current_token_pending_claims" */ - current_token_pending_claims: Array; - /** fetch data from the table: "current_token_pending_claims" using primary key columns */ - current_token_pending_claims_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "current_token_pending_claims" */ - current_token_pending_claims_stream: Array; - /** fetch data from the table: "delegated_staking_activities" */ - delegated_staking_activities: Array; - /** fetch data from the table: "delegated_staking_activities" using primary key columns */ - delegated_staking_activities_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "delegated_staking_activities" */ - delegated_staking_activities_stream: Array; - /** fetch data from the table: "events" */ - events: Array; - /** fetch data from the table: "events" using primary key columns */ - events_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "events" */ - events_stream: Array; - /** fetch data from the table: "indexer_status" */ - indexer_status: Array; - /** fetch data from the table: "indexer_status" using primary key columns */ - indexer_status_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "indexer_status" */ - indexer_status_stream: Array; - /** fetch data from the table: "ledger_infos" */ - ledger_infos: Array; - /** fetch data from the table: "ledger_infos" using primary key columns */ - ledger_infos_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "ledger_infos" */ - ledger_infos_stream: Array; - /** fetch data from the table: "move_resources" */ - move_resources: Array; - /** fetch aggregated fields from the table: "move_resources" */ - move_resources_aggregate: Move_Resources_Aggregate; - /** fetch data from the table in a streaming manner : "move_resources" */ - move_resources_stream: Array; - /** fetch data from the table: "processor_status" */ - processor_status: Array; - /** fetch data from the table: "processor_status" using primary key columns */ - processor_status_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "processor_status" */ - processor_status_stream: Array; - /** fetch data from the table: "proposal_votes" */ - proposal_votes: Array; - /** fetch aggregated fields from the table: "proposal_votes" */ - proposal_votes_aggregate: Proposal_Votes_Aggregate; - /** fetch data from the table: "proposal_votes" using primary key columns */ - proposal_votes_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "proposal_votes" */ - proposal_votes_stream: Array; - /** fetch data from the table: "table_items" */ - table_items: Array; - /** fetch data from the table: "table_items" using primary key columns */ - table_items_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "table_items" */ - table_items_stream: Array; - /** fetch data from the table: "table_metadatas" */ - table_metadatas: Array; - /** fetch data from the table: "table_metadatas" using primary key columns */ - table_metadatas_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "table_metadatas" */ - table_metadatas_stream: Array; - token_activities: Array; - token_activities_aggregate: Token_Activities_Aggregate; - /** fetch data from the table: "token_activities" using primary key columns */ - token_activities_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "token_activities" */ - token_activities_stream: Array; - /** fetch data from the table: "token_datas" */ - token_datas: Array; - /** fetch data from the table: "token_datas" using primary key columns */ - token_datas_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "token_datas" */ - token_datas_stream: Array; - /** fetch data from the table: "token_ownerships" */ - token_ownerships: Array; - /** fetch data from the table: "token_ownerships" using primary key columns */ - token_ownerships_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "token_ownerships" */ - token_ownerships_stream: Array; - /** fetch data from the table: "tokens" */ - tokens: Array; - /** fetch data from the table: "tokens" using primary key columns */ - tokens_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "tokens" */ - tokens_stream: Array; - /** fetch data from the table: "user_transactions" */ - user_transactions: Array; - /** fetch data from the table: "user_transactions" using primary key columns */ - user_transactions_by_pk?: Maybe; - /** fetch data from the table in a streaming manner : "user_transactions" */ - user_transactions_stream: Array; -}; - - -export type Subscription_RootAddress_Version_From_EventsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootAddress_Version_From_Events_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_Activities_By_PkArgs = { - event_account_address: Scalars['String']; - event_creation_number: Scalars['bigint']; - event_sequence_number: Scalars['bigint']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootCoin_Activities_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_BalancesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_Balances_By_PkArgs = { - coin_type_hash: Scalars['String']; - owner_address: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootCoin_Balances_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_InfosArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_Infos_By_PkArgs = { - coin_type_hash: Scalars['String']; -}; - - -export type Subscription_RootCoin_Infos_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_SupplyArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCoin_Supply_By_PkArgs = { - coin_type_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootCoin_Supply_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCollection_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCollection_Datas_By_PkArgs = { - collection_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootCollection_Datas_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Ans_LookupArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Ans_Lookup_By_PkArgs = { - domain: Scalars['String']; - subdomain: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Ans_Lookup_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Coin_BalancesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Coin_Balances_By_PkArgs = { - coin_type_hash: Scalars['String']; - owner_address: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Coin_Balances_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Collection_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Collection_Datas_By_PkArgs = { - collection_data_id_hash: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Collection_Datas_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Collection_Ownership_ViewArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Collection_Ownership_View_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Delegator_BalancesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Delegator_Balances_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Delegator_Balances_By_PkArgs = { - delegator_address: Scalars['String']; - pool_address: Scalars['String']; - pool_type: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Delegator_Balances_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Staking_Pool_VoterArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Staking_Pool_Voter_By_PkArgs = { - staking_pool_address: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Staking_Pool_Voter_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Table_ItemsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Table_Items_By_PkArgs = { - key_hash: Scalars['String']; - table_handle: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Table_Items_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Token_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Token_Datas_By_PkArgs = { - token_data_id_hash: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Token_Datas_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Token_OwnershipsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Token_Ownerships_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Token_Ownerships_By_PkArgs = { - owner_address: Scalars['String']; - property_version: Scalars['numeric']; - token_data_id_hash: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Token_Ownerships_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Token_Pending_ClaimsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootCurrent_Token_Pending_Claims_By_PkArgs = { - from_address: Scalars['String']; - property_version: Scalars['numeric']; - to_address: Scalars['String']; - token_data_id_hash: Scalars['String']; -}; - - -export type Subscription_RootCurrent_Token_Pending_Claims_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootDelegated_Staking_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootDelegated_Staking_Activities_By_PkArgs = { - event_index: Scalars['bigint']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootDelegated_Staking_Activities_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootEventsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootEvents_By_PkArgs = { - account_address: Scalars['String']; - creation_number: Scalars['bigint']; - sequence_number: Scalars['bigint']; -}; - - -export type Subscription_RootEvents_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootIndexer_StatusArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootIndexer_Status_By_PkArgs = { - db: Scalars['String']; -}; - - -export type Subscription_RootIndexer_Status_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootLedger_InfosArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootLedger_Infos_By_PkArgs = { - chain_id: Scalars['bigint']; -}; - - -export type Subscription_RootLedger_Infos_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootMove_ResourcesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootMove_Resources_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootMove_Resources_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootProcessor_StatusArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootProcessor_Status_By_PkArgs = { - processor: Scalars['String']; -}; - - -export type Subscription_RootProcessor_Status_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootProposal_VotesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootProposal_Votes_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootProposal_Votes_By_PkArgs = { - proposal_id: Scalars['bigint']; - transaction_version: Scalars['bigint']; - voter_address: Scalars['String']; -}; - - -export type Subscription_RootProposal_Votes_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootTable_ItemsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootTable_Items_By_PkArgs = { - transaction_version: Scalars['bigint']; - write_set_change_index: Scalars['bigint']; -}; - - -export type Subscription_RootTable_Items_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootTable_MetadatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootTable_Metadatas_By_PkArgs = { - handle: Scalars['String']; -}; - - -export type Subscription_RootTable_Metadatas_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootToken_ActivitiesArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootToken_Activities_AggregateArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootToken_Activities_By_PkArgs = { - event_account_address: Scalars['String']; - event_creation_number: Scalars['bigint']; - event_sequence_number: Scalars['bigint']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootToken_Activities_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootToken_DatasArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootToken_Datas_By_PkArgs = { - token_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootToken_Datas_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootToken_OwnershipsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootToken_Ownerships_By_PkArgs = { - property_version: Scalars['numeric']; - table_handle: Scalars['String']; - token_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootToken_Ownerships_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootTokensArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootTokens_By_PkArgs = { - property_version: Scalars['numeric']; - token_data_id_hash: Scalars['String']; - transaction_version: Scalars['bigint']; -}; - - -export type Subscription_RootTokens_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - - -export type Subscription_RootUser_TransactionsArgs = { - distinct_on?: InputMaybe>; - limit?: InputMaybe; - offset?: InputMaybe; - order_by?: InputMaybe>; - where?: InputMaybe; -}; - - -export type Subscription_RootUser_Transactions_By_PkArgs = { - version: Scalars['bigint']; -}; - - -export type Subscription_RootUser_Transactions_StreamArgs = { - batch_size: Scalars['Int']; - cursor: Array>; - where?: InputMaybe; -}; - -/** columns and relationships of "table_items" */ -export type Table_Items = { - __typename?: 'table_items'; - decoded_key: Scalars['jsonb']; - decoded_value?: Maybe; - key: Scalars['String']; - table_handle: Scalars['String']; - transaction_version: Scalars['bigint']; - write_set_change_index: Scalars['bigint']; -}; - - -/** columns and relationships of "table_items" */ -export type Table_ItemsDecoded_KeyArgs = { - path?: InputMaybe; -}; - - -/** columns and relationships of "table_items" */ -export type Table_ItemsDecoded_ValueArgs = { - path?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "table_items". All fields are combined with a logical 'AND'. */ -export type Table_Items_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - decoded_key?: InputMaybe; - decoded_value?: InputMaybe; - key?: InputMaybe; - table_handle?: InputMaybe; - transaction_version?: InputMaybe; - write_set_change_index?: InputMaybe; -}; - -/** Ordering options when selecting data from "table_items". */ -export type Table_Items_Order_By = { - decoded_key?: InputMaybe; - decoded_value?: InputMaybe; - key?: InputMaybe; - table_handle?: InputMaybe; - transaction_version?: InputMaybe; - write_set_change_index?: InputMaybe; -}; - -/** select columns of table "table_items" */ -export enum Table_Items_Select_Column { - /** column name */ - DecodedKey = 'decoded_key', - /** column name */ - DecodedValue = 'decoded_value', - /** column name */ - Key = 'key', - /** column name */ - TableHandle = 'table_handle', - /** column name */ - TransactionVersion = 'transaction_version', - /** column name */ - WriteSetChangeIndex = 'write_set_change_index' -} - -/** Streaming cursor of the table "table_items" */ -export type Table_Items_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Table_Items_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Table_Items_Stream_Cursor_Value_Input = { - decoded_key?: InputMaybe; - decoded_value?: InputMaybe; - key?: InputMaybe; - table_handle?: InputMaybe; - transaction_version?: InputMaybe; - write_set_change_index?: InputMaybe; -}; - -/** columns and relationships of "table_metadatas" */ -export type Table_Metadatas = { - __typename?: 'table_metadatas'; - handle: Scalars['String']; - key_type: Scalars['String']; - value_type: Scalars['String']; -}; - -/** Boolean expression to filter rows from the table "table_metadatas". All fields are combined with a logical 'AND'. */ -export type Table_Metadatas_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - handle?: InputMaybe; - key_type?: InputMaybe; - value_type?: InputMaybe; -}; - -/** Ordering options when selecting data from "table_metadatas". */ -export type Table_Metadatas_Order_By = { - handle?: InputMaybe; - key_type?: InputMaybe; - value_type?: InputMaybe; -}; - -/** select columns of table "table_metadatas" */ -export enum Table_Metadatas_Select_Column { - /** column name */ - Handle = 'handle', - /** column name */ - KeyType = 'key_type', - /** column name */ - ValueType = 'value_type' -} - -/** Streaming cursor of the table "table_metadatas" */ -export type Table_Metadatas_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Table_Metadatas_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Table_Metadatas_Stream_Cursor_Value_Input = { - handle?: InputMaybe; - key_type?: InputMaybe; - value_type?: InputMaybe; -}; - -/** Boolean expression to compare columns of type "timestamp". All fields are combined with logical 'AND'. */ -export type Timestamp_Comparison_Exp = { - _eq?: InputMaybe; - _gt?: InputMaybe; - _gte?: InputMaybe; - _in?: InputMaybe>; - _is_null?: InputMaybe; - _lt?: InputMaybe; - _lte?: InputMaybe; - _neq?: InputMaybe; - _nin?: InputMaybe>; -}; - -/** columns and relationships of "token_activities" */ -export type Token_Activities = { - __typename?: 'token_activities'; - coin_amount?: Maybe; - coin_type?: Maybe; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - /** An object relationship */ - current_token_data?: Maybe; - event_account_address: Scalars['String']; - event_creation_number: Scalars['bigint']; - event_index?: Maybe; - event_sequence_number: Scalars['bigint']; - from_address?: Maybe; - name: Scalars['String']; - property_version: Scalars['numeric']; - to_address?: Maybe; - token_amount: Scalars['numeric']; - token_data_id_hash: Scalars['String']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; - transfer_type: Scalars['String']; -}; - -/** aggregated selection of "token_activities" */ -export type Token_Activities_Aggregate = { - __typename?: 'token_activities_aggregate'; - aggregate?: Maybe; - nodes: Array; -}; - -/** aggregate fields of "token_activities" */ -export type Token_Activities_Aggregate_Fields = { - __typename?: 'token_activities_aggregate_fields'; - avg?: Maybe; - count: Scalars['Int']; - max?: Maybe; - min?: Maybe; - stddev?: Maybe; - stddev_pop?: Maybe; - stddev_samp?: Maybe; - sum?: Maybe; - var_pop?: Maybe; - var_samp?: Maybe; - variance?: Maybe; -}; - - -/** aggregate fields of "token_activities" */ -export type Token_Activities_Aggregate_FieldsCountArgs = { - columns?: InputMaybe>; - distinct?: InputMaybe; -}; - -/** aggregate avg on columns */ -export type Token_Activities_Avg_Fields = { - __typename?: 'token_activities_avg_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** Boolean expression to filter rows from the table "token_activities". All fields are combined with a logical 'AND'. */ -export type Token_Activities_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - coin_amount?: InputMaybe; - coin_type?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_token_data?: InputMaybe; - event_account_address?: InputMaybe; - event_creation_number?: InputMaybe; - event_index?: InputMaybe; - event_sequence_number?: InputMaybe; - from_address?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - to_address?: InputMaybe; - token_amount?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - transfer_type?: InputMaybe; -}; - -/** aggregate max on columns */ -export type Token_Activities_Max_Fields = { - __typename?: 'token_activities_max_fields'; - coin_amount?: Maybe; - coin_type?: Maybe; - collection_data_id_hash?: Maybe; - collection_name?: Maybe; - creator_address?: Maybe; - event_account_address?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - from_address?: Maybe; - name?: Maybe; - property_version?: Maybe; - to_address?: Maybe; - token_amount?: Maybe; - token_data_id_hash?: Maybe; - transaction_timestamp?: Maybe; - transaction_version?: Maybe; - transfer_type?: Maybe; -}; - -/** aggregate min on columns */ -export type Token_Activities_Min_Fields = { - __typename?: 'token_activities_min_fields'; - coin_amount?: Maybe; - coin_type?: Maybe; - collection_data_id_hash?: Maybe; - collection_name?: Maybe; - creator_address?: Maybe; - event_account_address?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - from_address?: Maybe; - name?: Maybe; - property_version?: Maybe; - to_address?: Maybe; - token_amount?: Maybe; - token_data_id_hash?: Maybe; - transaction_timestamp?: Maybe; - transaction_version?: Maybe; - transfer_type?: Maybe; -}; - -/** Ordering options when selecting data from "token_activities". */ -export type Token_Activities_Order_By = { - coin_amount?: InputMaybe; - coin_type?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - current_token_data?: InputMaybe; - event_account_address?: InputMaybe; - event_creation_number?: InputMaybe; - event_index?: InputMaybe; - event_sequence_number?: InputMaybe; - from_address?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - to_address?: InputMaybe; - token_amount?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - transfer_type?: InputMaybe; -}; - -/** select columns of table "token_activities" */ -export enum Token_Activities_Select_Column { - /** column name */ - CoinAmount = 'coin_amount', - /** column name */ - CoinType = 'coin_type', - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - EventAccountAddress = 'event_account_address', - /** column name */ - EventCreationNumber = 'event_creation_number', - /** column name */ - EventIndex = 'event_index', - /** column name */ - EventSequenceNumber = 'event_sequence_number', - /** column name */ - FromAddress = 'from_address', - /** column name */ - Name = 'name', - /** column name */ - PropertyVersion = 'property_version', - /** column name */ - ToAddress = 'to_address', - /** column name */ - TokenAmount = 'token_amount', - /** column name */ - TokenDataIdHash = 'token_data_id_hash', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version', - /** column name */ - TransferType = 'transfer_type' -} - -/** aggregate stddev on columns */ -export type Token_Activities_Stddev_Fields = { - __typename?: 'token_activities_stddev_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate stddev_pop on columns */ -export type Token_Activities_Stddev_Pop_Fields = { - __typename?: 'token_activities_stddev_pop_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate stddev_samp on columns */ -export type Token_Activities_Stddev_Samp_Fields = { - __typename?: 'token_activities_stddev_samp_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** Streaming cursor of the table "token_activities" */ -export type Token_Activities_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Token_Activities_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Token_Activities_Stream_Cursor_Value_Input = { - coin_amount?: InputMaybe; - coin_type?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - event_account_address?: InputMaybe; - event_creation_number?: InputMaybe; - event_index?: InputMaybe; - event_sequence_number?: InputMaybe; - from_address?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - to_address?: InputMaybe; - token_amount?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - transfer_type?: InputMaybe; -}; - -/** aggregate sum on columns */ -export type Token_Activities_Sum_Fields = { - __typename?: 'token_activities_sum_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate var_pop on columns */ -export type Token_Activities_Var_Pop_Fields = { - __typename?: 'token_activities_var_pop_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate var_samp on columns */ -export type Token_Activities_Var_Samp_Fields = { - __typename?: 'token_activities_var_samp_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** aggregate variance on columns */ -export type Token_Activities_Variance_Fields = { - __typename?: 'token_activities_variance_fields'; - coin_amount?: Maybe; - event_creation_number?: Maybe; - event_index?: Maybe; - event_sequence_number?: Maybe; - property_version?: Maybe; - token_amount?: Maybe; - transaction_version?: Maybe; -}; - -/** columns and relationships of "token_datas" */ -export type Token_Datas = { - __typename?: 'token_datas'; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - default_properties: Scalars['jsonb']; - description: Scalars['String']; - description_mutable: Scalars['Boolean']; - largest_property_version: Scalars['numeric']; - maximum: Scalars['numeric']; - maximum_mutable: Scalars['Boolean']; - metadata_uri: Scalars['String']; - name: Scalars['String']; - payee_address: Scalars['String']; - properties_mutable: Scalars['Boolean']; - royalty_mutable: Scalars['Boolean']; - royalty_points_denominator: Scalars['numeric']; - royalty_points_numerator: Scalars['numeric']; - supply: Scalars['numeric']; - token_data_id_hash: Scalars['String']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; - uri_mutable: Scalars['Boolean']; -}; - - -/** columns and relationships of "token_datas" */ -export type Token_DatasDefault_PropertiesArgs = { - path?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "token_datas". All fields are combined with a logical 'AND'. */ -export type Token_Datas_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - default_properties?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - largest_property_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - name?: InputMaybe; - payee_address?: InputMaybe; - properties_mutable?: InputMaybe; - royalty_mutable?: InputMaybe; - royalty_points_denominator?: InputMaybe; - royalty_points_numerator?: InputMaybe; - supply?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** Ordering options when selecting data from "token_datas". */ -export type Token_Datas_Order_By = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - default_properties?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - largest_property_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - name?: InputMaybe; - payee_address?: InputMaybe; - properties_mutable?: InputMaybe; - royalty_mutable?: InputMaybe; - royalty_points_denominator?: InputMaybe; - royalty_points_numerator?: InputMaybe; - supply?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** select columns of table "token_datas" */ -export enum Token_Datas_Select_Column { - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - DefaultProperties = 'default_properties', - /** column name */ - Description = 'description', - /** column name */ - DescriptionMutable = 'description_mutable', - /** column name */ - LargestPropertyVersion = 'largest_property_version', - /** column name */ - Maximum = 'maximum', - /** column name */ - MaximumMutable = 'maximum_mutable', - /** column name */ - MetadataUri = 'metadata_uri', - /** column name */ - Name = 'name', - /** column name */ - PayeeAddress = 'payee_address', - /** column name */ - PropertiesMutable = 'properties_mutable', - /** column name */ - RoyaltyMutable = 'royalty_mutable', - /** column name */ - RoyaltyPointsDenominator = 'royalty_points_denominator', - /** column name */ - RoyaltyPointsNumerator = 'royalty_points_numerator', - /** column name */ - Supply = 'supply', - /** column name */ - TokenDataIdHash = 'token_data_id_hash', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version', - /** column name */ - UriMutable = 'uri_mutable' -} - -/** Streaming cursor of the table "token_datas" */ -export type Token_Datas_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Token_Datas_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Token_Datas_Stream_Cursor_Value_Input = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - default_properties?: InputMaybe; - description?: InputMaybe; - description_mutable?: InputMaybe; - largest_property_version?: InputMaybe; - maximum?: InputMaybe; - maximum_mutable?: InputMaybe; - metadata_uri?: InputMaybe; - name?: InputMaybe; - payee_address?: InputMaybe; - properties_mutable?: InputMaybe; - royalty_mutable?: InputMaybe; - royalty_points_denominator?: InputMaybe; - royalty_points_numerator?: InputMaybe; - supply?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; - uri_mutable?: InputMaybe; -}; - -/** columns and relationships of "token_ownerships" */ -export type Token_Ownerships = { - __typename?: 'token_ownerships'; - amount: Scalars['numeric']; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - name: Scalars['String']; - owner_address?: Maybe; - property_version: Scalars['numeric']; - table_handle: Scalars['String']; - table_type?: Maybe; - token_data_id_hash: Scalars['String']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "token_ownerships". All fields are combined with a logical 'AND'. */ -export type Token_Ownerships_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_handle?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Ordering options when selecting data from "token_ownerships". */ -export type Token_Ownerships_Order_By = { - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_handle?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "token_ownerships" */ -export enum Token_Ownerships_Select_Column { - /** column name */ - Amount = 'amount', - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - Name = 'name', - /** column name */ - OwnerAddress = 'owner_address', - /** column name */ - PropertyVersion = 'property_version', - /** column name */ - TableHandle = 'table_handle', - /** column name */ - TableType = 'table_type', - /** column name */ - TokenDataIdHash = 'token_data_id_hash', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** Streaming cursor of the table "token_ownerships" */ -export type Token_Ownerships_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Token_Ownerships_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Token_Ownerships_Stream_Cursor_Value_Input = { - amount?: InputMaybe; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - name?: InputMaybe; - owner_address?: InputMaybe; - property_version?: InputMaybe; - table_handle?: InputMaybe; - table_type?: InputMaybe; - token_data_id_hash?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** columns and relationships of "tokens" */ -export type Tokens = { - __typename?: 'tokens'; - collection_data_id_hash: Scalars['String']; - collection_name: Scalars['String']; - creator_address: Scalars['String']; - name: Scalars['String']; - property_version: Scalars['numeric']; - token_data_id_hash: Scalars['String']; - token_properties: Scalars['jsonb']; - transaction_timestamp: Scalars['timestamp']; - transaction_version: Scalars['bigint']; -}; - - -/** columns and relationships of "tokens" */ -export type TokensToken_PropertiesArgs = { - path?: InputMaybe; -}; - -/** Boolean expression to filter rows from the table "tokens". All fields are combined with a logical 'AND'. */ -export type Tokens_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - token_data_id_hash?: InputMaybe; - token_properties?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** Ordering options when selecting data from "tokens". */ -export type Tokens_Order_By = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - token_data_id_hash?: InputMaybe; - token_properties?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** select columns of table "tokens" */ -export enum Tokens_Select_Column { - /** column name */ - CollectionDataIdHash = 'collection_data_id_hash', - /** column name */ - CollectionName = 'collection_name', - /** column name */ - CreatorAddress = 'creator_address', - /** column name */ - Name = 'name', - /** column name */ - PropertyVersion = 'property_version', - /** column name */ - TokenDataIdHash = 'token_data_id_hash', - /** column name */ - TokenProperties = 'token_properties', - /** column name */ - TransactionTimestamp = 'transaction_timestamp', - /** column name */ - TransactionVersion = 'transaction_version' -} - -/** Streaming cursor of the table "tokens" */ -export type Tokens_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: Tokens_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type Tokens_Stream_Cursor_Value_Input = { - collection_data_id_hash?: InputMaybe; - collection_name?: InputMaybe; - creator_address?: InputMaybe; - name?: InputMaybe; - property_version?: InputMaybe; - token_data_id_hash?: InputMaybe; - token_properties?: InputMaybe; - transaction_timestamp?: InputMaybe; - transaction_version?: InputMaybe; -}; - -/** columns and relationships of "user_transactions" */ -export type User_Transactions = { - __typename?: 'user_transactions'; - block_height: Scalars['bigint']; - entry_function_id_str: Scalars['String']; - epoch: Scalars['bigint']; - expiration_timestamp_secs: Scalars['timestamp']; - gas_unit_price: Scalars['numeric']; - max_gas_amount: Scalars['numeric']; - parent_signature_type: Scalars['String']; - sender: Scalars['String']; - sequence_number: Scalars['bigint']; - timestamp: Scalars['timestamp']; - version: Scalars['bigint']; -}; - -/** Boolean expression to filter rows from the table "user_transactions". All fields are combined with a logical 'AND'. */ -export type User_Transactions_Bool_Exp = { - _and?: InputMaybe>; - _not?: InputMaybe; - _or?: InputMaybe>; - block_height?: InputMaybe; - entry_function_id_str?: InputMaybe; - epoch?: InputMaybe; - expiration_timestamp_secs?: InputMaybe; - gas_unit_price?: InputMaybe; - max_gas_amount?: InputMaybe; - parent_signature_type?: InputMaybe; - sender?: InputMaybe; - sequence_number?: InputMaybe; - timestamp?: InputMaybe; - version?: InputMaybe; -}; - -/** Ordering options when selecting data from "user_transactions". */ -export type User_Transactions_Order_By = { - block_height?: InputMaybe; - entry_function_id_str?: InputMaybe; - epoch?: InputMaybe; - expiration_timestamp_secs?: InputMaybe; - gas_unit_price?: InputMaybe; - max_gas_amount?: InputMaybe; - parent_signature_type?: InputMaybe; - sender?: InputMaybe; - sequence_number?: InputMaybe; - timestamp?: InputMaybe; - version?: InputMaybe; -}; - -/** select columns of table "user_transactions" */ -export enum User_Transactions_Select_Column { - /** column name */ - BlockHeight = 'block_height', - /** column name */ - EntryFunctionIdStr = 'entry_function_id_str', - /** column name */ - Epoch = 'epoch', - /** column name */ - ExpirationTimestampSecs = 'expiration_timestamp_secs', - /** column name */ - GasUnitPrice = 'gas_unit_price', - /** column name */ - MaxGasAmount = 'max_gas_amount', - /** column name */ - ParentSignatureType = 'parent_signature_type', - /** column name */ - Sender = 'sender', - /** column name */ - SequenceNumber = 'sequence_number', - /** column name */ - Timestamp = 'timestamp', - /** column name */ - Version = 'version' -} - -/** Streaming cursor of the table "user_transactions" */ -export type User_Transactions_Stream_Cursor_Input = { - /** Stream column input with initial value */ - initial_value: User_Transactions_Stream_Cursor_Value_Input; - /** cursor ordering */ - ordering?: InputMaybe; -}; - -/** Initial value of the column from where the streaming should start */ -export type User_Transactions_Stream_Cursor_Value_Input = { - block_height?: InputMaybe; - entry_function_id_str?: InputMaybe; - epoch?: InputMaybe; - expiration_timestamp_secs?: InputMaybe; - gas_unit_price?: InputMaybe; - max_gas_amount?: InputMaybe; - parent_signature_type?: InputMaybe; - sender?: InputMaybe; - sequence_number?: InputMaybe; - timestamp?: InputMaybe; - version?: InputMaybe; -}; diff --git a/m1/JavaScript-client/src/indexer/queries/getAccountCoinsData.graphql b/m1/JavaScript-client/src/indexer/queries/getAccountCoinsData.graphql deleted file mode 100644 index 15bb54c62..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getAccountCoinsData.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query getAccountCoinsData($owner_address: String, $offset: Int, $limit: Int) { - current_coin_balances(where: { owner_address: { _eq: $owner_address } }, offset: $offset, limit: $limit) { - amount - coin_type - coin_info { - name - decimals - symbol - } - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getAccountCurrentTokens.graphql b/m1/JavaScript-client/src/indexer/queries/getAccountCurrentTokens.graphql deleted file mode 100644 index 87dc86c55..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getAccountCurrentTokens.graphql +++ /dev/null @@ -1,38 +0,0 @@ -query getAccountCurrentTokens($address: String!, $offset: Int, $limit: Int) { - current_token_ownerships( - where: { owner_address: { _eq: $address }, amount: { _gt: 0 } } - order_by: [{ last_transaction_version: desc }, { creator_address: asc }, { collection_name: asc }, { name: asc }] - offset: $offset - limit: $limit - ) { - amount - current_token_data { - ...TokenDataFields - } - current_collection_data { - ...CollectionDataFields - } - last_transaction_version - property_version - } -} - -fragment TokenDataFields on current_token_datas { - creator_address - collection_name - description - metadata_uri - name - token_data_id_hash - collection_data_id_hash -} - -fragment CollectionDataFields on current_collection_datas { - metadata_uri - supply - description - collection_name - collection_data_id_hash - table_handle - creator_address -} diff --git a/m1/JavaScript-client/src/indexer/queries/getAccountTokensCount.graphql b/m1/JavaScript-client/src/indexer/queries/getAccountTokensCount.graphql deleted file mode 100644 index 0ce7eb9d5..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getAccountTokensCount.graphql +++ /dev/null @@ -1,7 +0,0 @@ -query getAccountTokensCount($owner_address: String) { - current_token_ownerships_aggregate(where: { owner_address: { _eq: $owner_address }, amount: { _gt: "0" } }) { - aggregate { - count - } - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getAccountTransactionsCount.graphql b/m1/JavaScript-client/src/indexer/queries/getAccountTransactionsCount.graphql deleted file mode 100644 index e27c6e7a6..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getAccountTransactionsCount.graphql +++ /dev/null @@ -1,7 +0,0 @@ -query getAccountTransactionsCount($address: String) { - move_resources_aggregate(where: { address: { _eq: $address } }, distinct_on: transaction_version) { - aggregate { - count - } - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getAccountTransactionsData.graphql b/m1/JavaScript-client/src/indexer/queries/getAccountTransactionsData.graphql deleted file mode 100644 index 3a9ac0ce8..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getAccountTransactionsData.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query getAccountTransactionsData($address: String, $limit: Int, $offset: Int) { - move_resources( - where: { address: { _eq: $address } } - order_by: { transaction_version: desc } - distinct_on: transaction_version - limit: $limit - offset: $offset - ) { - transaction_version - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getCurrentDelegatorBalancesCount.graphql b/m1/JavaScript-client/src/indexer/queries/getCurrentDelegatorBalancesCount.graphql deleted file mode 100644 index a07f051e8..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getCurrentDelegatorBalancesCount.graphql +++ /dev/null @@ -1,10 +0,0 @@ -query getCurrentDelegatorBalancesCount($poolAddress: String) { - current_delegator_balances_aggregate( - where: { pool_type: { _eq: "active_shares" }, pool_address: { _eq: $poolAddress }, amount: { _gt: "0" } } - distinct_on: delegator_address - ) { - aggregate { - count - } - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getDelegatedStakingActivities.graphql b/m1/JavaScript-client/src/indexer/queries/getDelegatedStakingActivities.graphql deleted file mode 100644 index 70083e243..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getDelegatedStakingActivities.graphql +++ /dev/null @@ -1,12 +0,0 @@ -query getDelegatedStakingActivities($delegatorAddress: String, $poolAddress: String) { - delegated_staking_activities( - where: { delegator_address: { _eq: $delegatorAddress }, pool_address: { _eq: $poolAddress } } - ) { - amount - delegator_address - event_index - event_type - pool_address - transaction_version - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getLedgerInfo.graphql b/m1/JavaScript-client/src/indexer/queries/getLedgerInfo.graphql deleted file mode 100644 index c4c6eb476..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getLedgerInfo.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query getIndexerLedgerInfo { - ledger_infos { - chain_id - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getTokenActivities.graphql b/m1/JavaScript-client/src/indexer/queries/getTokenActivities.graphql deleted file mode 100644 index ab7af8887..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getTokenActivities.graphql +++ /dev/null @@ -1,22 +0,0 @@ -query getTokenActivities($idHash: String!, $offset: Int, $limit: Int) { - token_activities( - where: { token_data_id_hash: { _eq: $idHash } } - order_by: { transaction_version: desc } - offset: $offset - limit: $limit - ) { - creator_address - collection_name - name - token_data_id_hash - collection_data_id_hash - from_address - to_address - transaction_version - transaction_timestamp - property_version - transfer_type - event_sequence_number - token_amount - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getTokenActivitiesCount.graphql b/m1/JavaScript-client/src/indexer/queries/getTokenActivitiesCount.graphql deleted file mode 100644 index 6f8d2e994..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getTokenActivitiesCount.graphql +++ /dev/null @@ -1,7 +0,0 @@ -query getTokenActivitiesCount($token_id: String) { - token_activities_aggregate(where: { token_data_id_hash: { _eq: $token_id } }) { - aggregate { - count - } - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getTokenData.graphql b/m1/JavaScript-client/src/indexer/queries/getTokenData.graphql deleted file mode 100644 index 3fec6d925..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getTokenData.graphql +++ /dev/null @@ -1,16 +0,0 @@ -query getTokenData($token_id: String) { - current_token_datas(where: { token_data_id_hash: { _eq: $token_id } }) { - token_data_id_hash - name - collection_name - creator_address - default_properties - largest_property_version - maximum - metadata_uri - payee_address - royalty_points_denominator - royalty_points_numerator - supply - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getTokenOwnersData.graphql b/m1/JavaScript-client/src/indexer/queries/getTokenOwnersData.graphql deleted file mode 100644 index 3dcc3dece..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getTokenOwnersData.graphql +++ /dev/null @@ -1,7 +0,0 @@ -query getTokenOwnersData($token_id: String, $property_version: numeric) { - current_token_ownerships( - where: { token_data_id_hash: { _eq: $token_id }, property_version: { _eq: $property_version } } - ) { - owner_address - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getTopUserTransactions.graphql b/m1/JavaScript-client/src/indexer/queries/getTopUserTransactions.graphql deleted file mode 100644 index b93cbc858..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getTopUserTransactions.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query getTopUserTransactions($limit: Int) { - user_transactions(limit: $limit, order_by: { version: desc }) { - version - } -} diff --git a/m1/JavaScript-client/src/indexer/queries/getUserTransactions.graphql b/m1/JavaScript-client/src/indexer/queries/getUserTransactions.graphql deleted file mode 100644 index 529f43ac3..000000000 --- a/m1/JavaScript-client/src/indexer/queries/getUserTransactions.graphql +++ /dev/null @@ -1,10 +0,0 @@ -query getUserTransactions($limit: Int, $start_version: bigint, $offset: Int) { - user_transactions( - limit: $limit - order_by: { version: desc } - where: { version: { _lte: $start_version } } - offset: $offset - ) { - version - } -} diff --git a/m1/JavaScript-client/src/plugins/ans_client.ts b/m1/JavaScript-client/src/plugins/ans_client.ts deleted file mode 100644 index 7fe21411d..000000000 --- a/m1/JavaScript-client/src/plugins/ans_client.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { AptosClient, ApiError, Provider, OptionalTransactionArgs } from "../providers"; -import * as Gen from "../generated/index"; -import { AptosAccount } from "../account"; -import { TransactionBuilderRemoteABI } from "../transaction_builder"; - -const ansContractsMap: Record = { - testnet: "0x5f8fd2347449685cf41d4db97926ec3a096eaf381332be4f1318ad4d16a8497c", - mainnet: "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", -}; - -// Each name component can only have lowercase letters, number or hyphens, and cannot start or end with a hyphen. -const nameComponentPattern = /^[a-z\d][a-z\d-]{1,61}[a-z\d]$/; - -const namePattern = new RegExp( - "^" + - // Optional subdomain (cannot be followed by .apt) - "(?:(?[^.]+)\\.(?!apt$))?" + - // Domain - "(?[^.]+)" + - // Optional .apt suffix - "(?:\\.apt)?" + - "$", -); - -type ReverseLookupRegistryV1 = { - registry: { - handle: string; - }; -}; - -type NameRegistryV1 = { - registry: { - handle: string; - }; -}; - -export class AnsClient { - contractAddress: string; - - provider: Provider; - - /** - * Creates new AnsClient instance - * @param provider Provider instance - * @param contractAddress An optional contract address. - * If there is no contract address matching to the provided network - * then the AnsClient class expects a contract address - - * this is to support both mainnet/testnet networks and local development. - */ - constructor(provider: Provider, contractAddress?: string) { - this.provider = provider; - if (!ansContractsMap[this.provider.network] && !contractAddress) { - throw new Error("Error: For custom providers, you must pass in a contract address"); - } - this.contractAddress = ansContractsMap[this.provider.network] ?? contractAddress; - } - - /** - * Returns the primary name for the given account address - * @param address An account address - * @returns Account's primary name | null if there is no primary name defined - */ - async getPrimaryNameByAddress(address: string): Promise { - const ansResource: Gen.MoveResource = await this.provider.getAccountResource( - this.contractAddress, - `${this.contractAddress}::domains::ReverseLookupRegistryV1`, - ); - const data = ansResource.data as ReverseLookupRegistryV1; - const { handle } = data.registry; - const domainsTableItemRequest = { - key_type: "address", - value_type: `${this.contractAddress}::domains::NameRecordKeyV1`, - key: address, - }; - try { - const item = await this.provider.getTableItem(handle, domainsTableItemRequest); - return item.subdomain_name.vec[0] ? `${item.subdomain_name.vec[0]}.${item.domain_name}` : item.domain_name; - } catch (error: any) { - // if item not found, response is 404 error - meaning item not found - if (error.status === 404) { - return null; - } - throw new Error(error); - } - } - - /** - * Returns the target account address for the given name - * @param name ANS name - * @returns Account address | null - */ - async getAddressByName(name: string): Promise { - const { domain, subdomain } = name.match(namePattern)?.groups ?? {}; - if (!domain) return null; - if (subdomain) return this.getAddressBySubdomainName(domain, subdomain); - return this.getAddressByDomainName(domain); - } - - /** - * Mint a new Aptos name - * - * @param account AptosAccount where collection will be created - * @param domainName Aptos domain name to mint - * @param years year duration of the domain name - * @returns The hash of the pending transaction submitted to the API - */ - async mintAptosName( - account: AptosAccount, - domainName: string, - years: number = 1, - extraArgs?: OptionalTransactionArgs, - ): Promise { - // check if the name is valid - if (domainName.match(nameComponentPattern) === null) { - throw new ApiError(400, `Name ${domainName} is not valid`); - } - // check if the name is available - const address = await this.getAddressByName(domainName); - if (address !== null) { - throw new ApiError(400, `Name ${domainName} is not available`); - } - - const builder = new TransactionBuilderRemoteABI(this.provider.aptosClient, { - sender: account.address(), - ...extraArgs, - }); - const rawTxn = await builder.build(`${this.contractAddress}::domains::register_domain`, [], [domainName, years]); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.provider.submitSignedBCSTransaction(bcsTxn); - - return pendingTransaction.hash; - } - - /** - * Initialize reverse lookup for contract owner - * - * @param owner the `aptos_names` AptosAccount - * @returns The hash of the pending transaction submitted to the API - */ - async initReverseLookupRegistry(owner: AptosAccount, extraArgs?: OptionalTransactionArgs): Promise { - const builder = new TransactionBuilderRemoteABI(this.provider.aptosClient, { - sender: owner.address(), - ...extraArgs, - }); - const rawTxn = await builder.build(`${this.contractAddress}::domains::init_reverse_lookup_registry_v1`, [], []); - - const bcsTxn = AptosClient.generateBCSTransaction(owner, rawTxn); - const pendingTransaction = await this.provider.submitSignedBCSTransaction(bcsTxn); - - return pendingTransaction.hash; - } - - /** - * Returns the account address for the given domain name - * @param domain domain name - * @example - * if name is `aptos.apt` - * domain = aptos - * - * @returns account address | null - */ - private async getAddressByDomainName(domain: string) { - if (domain.match(nameComponentPattern) === null) return null; - const ansResource: { type: Gen.MoveStructTag; data: any } = await this.provider.getAccountResource( - this.contractAddress, - `${this.contractAddress}::domains::NameRegistryV1`, - ); - const data = ansResource.data as NameRegistryV1; - const { handle } = data.registry; - const domainsTableItemRequest = { - key_type: `${this.contractAddress}::domains::NameRecordKeyV1`, - value_type: `${this.contractAddress}::domains::NameRecordV1`, - key: { - subdomain_name: { vec: [] }, - domain_name: domain, - }, - }; - - try { - const item = await this.provider.getTableItem(handle, domainsTableItemRequest); - return item.target_address.vec[0]; - } catch (error: any) { - // if item not found, response is 404 error - meaning item not found - if (error.status === 404) { - return null; - } - throw new Error(error); - } - } - - /** - * Returns the account address for the given subdomain_name - * @param domain domain name - * @param subdomain subdomain name - * @example - * if name is `dev.aptos.apt` - * domain = aptos - * subdomain = dev - * - * @returns account address | null - */ - private async getAddressBySubdomainName(domain: string, subdomain: string): Promise { - if (domain.match(nameComponentPattern) === null) return null; - if (subdomain.match(nameComponentPattern) === null) return null; - const ansResource: { type: Gen.MoveStructTag; data: any } = await this.provider.getAccountResource( - this.contractAddress, - `${this.contractAddress}::domains::NameRegistryV1`, - ); - const data = ansResource.data as NameRegistryV1; - const { handle } = data.registry; - const domainsTableItemRequest = { - key_type: `${this.contractAddress}::domains::NameRecordKeyV1`, - value_type: `${this.contractAddress}::domains::NameRecordV1`, - key: { - subdomain_name: { vec: [subdomain] }, - domain_name: domain, - }, - }; - - try { - const item = await this.provider.getTableItem(handle, domainsTableItemRequest); - return item.target_address.vec[0]; - } catch (error: any) { - // if item not found, response is 404 error - meaning item not found - if (error.status === 404) { - return null; - } - throw new Error(error); - } - } -} diff --git a/m1/JavaScript-client/src/plugins/aptos_token.ts b/m1/JavaScript-client/src/plugins/aptos_token.ts deleted file mode 100644 index 5d98bb8a4..000000000 --- a/m1/JavaScript-client/src/plugins/aptos_token.ts +++ /dev/null @@ -1,490 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable max-len */ - -import { AptosAccount } from "../account/aptos_account"; -import { AnyNumber } from "../bcs"; -import { MAX_U64_BIG_INT } from "../bcs/consts"; -import { Provider } from "../providers"; -import { AptosClient, OptionalTransactionArgs } from "../providers/aptos_client"; -import { TransactionBuilderRemoteABI } from "../transaction_builder"; -import { HexString, MaybeHexString } from "../utils"; -import { getPropertyValueRaw, getSinglePropertyValueRaw } from "../utils/property_map_serde"; - -export interface CreateCollectionOptions { - royaltyNumerator?: number; - royaltyDenominator?: number; - mutableDescription?: boolean; - mutableRoyalty?: boolean; - mutableURI?: boolean; - mutableTokenDescription?: boolean; - mutableTokenName?: boolean; - mutableTokenProperties?: boolean; - mutableTokenURI?: boolean; - tokensBurnableByCreator?: boolean; - tokensFreezableByCreator?: boolean; -} - -const PropertyTypeMap = { - BOOLEAN: "bool", - U8: "u8", - U16: "u16", - U32: "u32", - U64: "u64", - U128: "u128", - U256: "u256", - ADDRESS: "address", - VECTOR: "vector", - STRING: "string", -}; - -export type PropertyType = keyof typeof PropertyTypeMap; - -/** - * Class for managing aptos_token - */ -export class AptosToken { - readonly provider: Provider; - - private readonly tokenType: string = "0x4::token::Token"; - - /** - * Creates new AptosToken instance - * - * @param provider Provider instance - */ - constructor(provider: Provider) { - this.provider = provider; - } - - private async submitTransaction( - account: AptosAccount, - funcName: string, - typeArgs: string[], - args: any[], - extraArgs?: OptionalTransactionArgs, - ) { - const builder = new TransactionBuilderRemoteABI(this.provider, { - sender: account.address(), - ...extraArgs, - }); - const rawTxn = await builder.build(`0x4::aptos_token::${funcName}`, typeArgs, args); - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.provider.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Creates a new collection within the specified account - * - * @param creator AptosAccount where collection will be created - * @param description Collection description - * @param name Collection name - * @param uri URL to additional info about collection - * @param options CreateCollectionOptions type. By default all values set to `true` or `0` - * @returns The hash of the transaction submitted to the API - */ - async createCollection( - creator: AptosAccount, - description: string, - name: string, - uri: string, - maxSupply: AnyNumber = MAX_U64_BIG_INT, - options?: CreateCollectionOptions, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "create_collection", - [], - [ - description, - maxSupply, - name, - uri, - options?.mutableDescription ?? true, - options?.mutableRoyalty ?? true, - options?.mutableURI ?? true, - options?.mutableTokenDescription ?? true, - options?.mutableTokenName ?? true, - options?.mutableTokenProperties ?? true, - options?.mutableTokenURI ?? true, - options?.tokensBurnableByCreator ?? true, - options?.tokensFreezableByCreator ?? true, - options?.royaltyNumerator ?? 0, - options?.royaltyDenominator ?? 0, - ], - extraArgs, - ); - } - - /** - * Mint a new token within the specified account - * - * @param account AptosAccount where token will be created - * @param collection Name of collection, that token belongs to - * @param description Token description - * @param name Token name - * @param uri URL to additional info about token - * @param propertyKeys the property keys for storing on-chain properties - * @param propertyTypes the type of property values - * @param propertyValues the property values to be stored on-chain - * @returns The hash of the transaction submitted to the API - */ - async mint( - account: AptosAccount, - collection: string, - description: string, - name: string, - uri: string, - propertyKeys: Array = [], - propertyTypes: Array = [], - propertyValues: Array = [], - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - account, - "mint", - [], - [ - collection, - description, - name, - uri, - propertyKeys, - propertyTypes, - getPropertyValueRaw(propertyValues, propertyTypes), - ], - extraArgs, - ); - } - - /** - * Mint a soul bound token into a recipient's account - * - * @param account AptosAccount that mints the token - * @param collection Name of collection, that token belongs to - * @param description Token description - * @param name Token name - * @param uri URL to additional info about token - * @param recipient AptosAccount where token will be created - * @param propertyKeys the property keys for storing on-chain properties - * @param propertyTypes the type of property values - * @param propertyValues the property values to be stored on-chain - * @returns The hash of the transaction submitted to the API - */ - async mintSoulBound( - account: AptosAccount, - collection: string, - description: string, - name: string, - uri: string, - recipient: AptosAccount, - propertyKeys: Array = [], - propertyTypes: Array = [], - propertyValues: Array = [], - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - account, - "mint_soul_bound", - [], - [ - collection, - description, - name, - uri, - propertyKeys, - propertyTypes, - getPropertyValueRaw(propertyValues, propertyTypes), - recipient.address().hex(), - ], - extraArgs, - ); - } - - /** - * Burn a token by its creator - * @param creator Creator account - * @param token Token address - * @returns The hash of the transaction submitted to the API - */ - async burnToken( - creator: AptosAccount, - token: MaybeHexString, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "burn", - [tokenType || this.tokenType], - [HexString.ensure(token).hex()], - extraArgs, - ); - } - - /** - * Freeze token transfer ability - * @param creator Creator account - * @param token Token address - * @returns The hash of the transaction submitted to the API - */ - async freezeTokenTransafer( - creator: AptosAccount, - token: MaybeHexString, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "freeze_transfer", - [tokenType || this.tokenType], - [HexString.ensure(token).hex()], - extraArgs, - ); - } - - /** - * Unfreeze token transfer ability - * @param creator Creator account - * @param token Token address - * @returns The hash of the transaction submitted to the API - */ - async unfreezeTokenTransafer( - creator: AptosAccount, - token: MaybeHexString, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "unfreeze_transfer", - [tokenType || this.tokenType], - [HexString.ensure(token).hex()], - extraArgs, - ); - } - - /** - * Set token description - * @param creator Creator account - * @param token Token address - * @param description Token description - * @returns The hash of the transaction submitted to the API - */ - async setTokenDescription( - creator: AptosAccount, - token: MaybeHexString, - description: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "set_description", - [tokenType || this.tokenType], - [HexString.ensure(token).hex(), description], - extraArgs, - ); - } - - /** - * Set token name - * @param creator Creator account - * @param token Token address - * @param name Token name - * @returns The hash of the transaction submitted to the API - */ - async setTokenName( - creator: AptosAccount, - token: MaybeHexString, - name: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "set_name", - [tokenType || this.tokenType], - [HexString.ensure(token).hex(), name], - extraArgs, - ); - } - - /** - * Set token URI - * @param creator Creator account - * @param token Token address - * @param uri Token uri - * @returns The hash of the transaction submitted to the API - */ - async setTokenURI( - creator: AptosAccount, - token: MaybeHexString, - uri: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "set_uri", - [tokenType || this.tokenType], - [HexString.ensure(token).hex(), uri], - extraArgs, - ); - } - - /** - * Add token property - * @param creator Creator account - * @param token Token address - * @param key the property key for storing on-chain property - * @param type the type of property value - * @param value the property value to be stored on-chain - * @returns The hash of the transaction submitted to the API - */ - async addTokenProperty( - creator: AptosAccount, - token: MaybeHexString, - propertyKey: string, - propertyType: PropertyType, - propertyValue: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "add_property", - [tokenType || this.tokenType], - [ - HexString.ensure(token).hex(), - propertyKey, - PropertyTypeMap[propertyType], - getSinglePropertyValueRaw(propertyValue, PropertyTypeMap[propertyType]), - ], - extraArgs, - ); - } - - /** - * Remove token property - * @param creator Creator account - * @param token Token address - * @param key the property key stored on-chain - * @returns The hash of the transaction submitted to the API - */ - async removeTokenProperty( - creator: AptosAccount, - token: MaybeHexString, - propertyKey: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "remove_property", - [tokenType || this.tokenType], - [HexString.ensure(token).hex(), propertyKey], - extraArgs, - ); - } - - /** - * Update token property - * @param creator Creator account - * @param token Token address - * @param key the property key stored on-chain - * @param type the property typed stored on-chain - * @param value the property value to be stored on-chain - * @returns The hash of the transaction submitted to the API - */ - async updateTokenProperty( - creator: AptosAccount, - token: MaybeHexString, - propertyKey: string, - propertyType: PropertyType, - propertyValue: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - return this.submitTransaction( - creator, - "update_property", - [tokenType || this.tokenType], - [ - HexString.ensure(token).hex(), - propertyKey, - PropertyTypeMap[propertyType], - getSinglePropertyValueRaw(propertyValue, PropertyTypeMap[propertyType]), - ], - extraArgs, - ); - } - - async addTypedProperty( - creator: AptosAccount, - token: MaybeHexString, - propertyKey: string, - propertyType: PropertyType, - propertyValue: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ) { - return this.submitTransaction( - creator, - "add_typed_property", - [tokenType || this.tokenType, PropertyTypeMap[propertyType]], - [HexString.ensure(token).hex(), propertyKey, propertyValue], - extraArgs, - ); - } - - async updateTypedProperty( - creator: AptosAccount, - token: MaybeHexString, - propertyKey: string, - propertyType: PropertyType, - propertyValue: string, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ) { - return this.submitTransaction( - creator, - "update_typed_property", - [tokenType || this.tokenType, PropertyTypeMap[propertyType]], - [HexString.ensure(token).hex(), propertyKey, propertyValue], - extraArgs, - ); - } - - /** - * Transfer a token ownership. - * We can transfer a token only when the token is not frozen (i.e. owner transfer is not disabled such as for soul bound tokens) - * @param owner The account of the current token owner - * @param token Token address - * @param recipient Recipient address - * @returns The hash of the transaction submitted to the API - */ - async transferTokenOwnership( - owner: AptosAccount, - token: MaybeHexString, - recipient: MaybeHexString, - tokenType?: string, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.provider.aptosClient, { - sender: owner.address(), - ...extraArgs, - }); - const rawTxn = await builder.build( - "0x1::object::transfer", - [tokenType || this.tokenType], - [HexString.ensure(token).hex(), HexString.ensure(recipient).hex()], - ); - const bcsTxn = AptosClient.generateBCSTransaction(owner, rawTxn); - const pendingTransaction = await this.provider.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } -} diff --git a/m1/JavaScript-client/src/plugins/coin_client.ts b/m1/JavaScript-client/src/plugins/coin_client.ts deleted file mode 100644 index 8eff1e09d..000000000 --- a/m1/JavaScript-client/src/plugins/coin_client.ts +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AptosAccount, getAddressFromAccountOrAddress } from "../account/aptos_account"; -import { AptosClient, OptionalTransactionArgs } from "../providers/aptos_client"; -import { MaybeHexString, APTOS_COIN } from "../utils"; -import { TransactionBuilderRemoteABI } from "../transaction_builder"; - -/** - * Class for working with the coin module, such as transferring coins and - * checking balances. - */ -export class CoinClient { - aptosClient: AptosClient; - - /** - * Creates new CoinClient instance - * @param aptosClient AptosClient instance - */ - constructor(aptosClient: AptosClient) { - this.aptosClient = aptosClient; - } - - /** - * Generate, sign, and submit a transaction to the Aptos blockchain API to - * transfer coins from one account to another. By default it transfers - * 0x1::aptos_coin::AptosCoin, but you can specify a different coin type - * with the `coinType` argument. - * - * You may set `createReceiverIfMissing` to true if you want to create the - * receiver account if it does not exist on chain yet. If you do not set - * this to true, the transaction will fail if the receiver account does not - * exist on-chain. - * - * @param from Account sending the coins - * @param to Account to receive the coins - * @param amount Number of coins to transfer - * @param extraArgs Extra args for building the transaction or configuring how - * the client should submit and wait for the transaction - * @returns The hash of the transaction submitted to the API - */ - // :!:>transfer - async transfer( - from: AptosAccount, - to: AptosAccount | MaybeHexString, - amount: number | bigint, - extraArgs?: OptionalTransactionArgs & { - // The coin type to use, defaults to 0x1::aptos_coin::AptosCoin - coinType?: string; - // If set, create the `receiver` account if it doesn't exist on-chain. - // This is done by calling `0x1::aptos_account::transfer` instead, which - // will create the account on-chain first if it doesn't exist before - // transferring the coins to it. - // If this is the first time an account has received the specified coinType, - // and this is set to false, the transaction would fail. - createReceiverIfMissing?: boolean; - }, - ): Promise { - // If none is explicitly given, use 0x1::aptos_coin::AptosCoin as the coin type. - const coinTypeToTransfer = extraArgs?.coinType ?? APTOS_COIN; - - // If we should create the receiver account if it doesn't exist on-chain, - // use the `0x1::aptos_account::transfer` function. - const func = extraArgs?.createReceiverIfMissing ? "0x1::aptos_account::transfer_coins" : "0x1::coin::transfer"; - - // Get the receiver address from the AptosAccount or MaybeHexString. - const toAddress = getAddressFromAccountOrAddress(to); - - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: from.address(), ...extraArgs }); - const rawTxn = await builder.build(func, [coinTypeToTransfer], [toAddress, amount]); - - const bcsTxn = AptosClient.generateBCSTransaction(from, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } // <:!:transfer - - /** - * Get the balance of the account. By default it checks the balance of - * 0x1::aptos_coin::AptosCoin, but you can specify a different coin type. - * - * @param account Account that you want to get the balance of. - * @param extraArgs Extra args for checking the balance. - * @returns Promise that resolves to the balance as a bigint. - */ - // :!:>checkBalance - async checkBalance( - account: AptosAccount | MaybeHexString, - extraArgs?: { - // The coin type to use, defaults to 0x1::aptos_coin::AptosCoin - coinType?: string; - }, - ): Promise { - const coinType = extraArgs?.coinType ?? APTOS_COIN; - const typeTag = `0x1::coin::CoinStore<${coinType}>`; - const address = getAddressFromAccountOrAddress(account); - const accountResource = await this.aptosClient.getAccountResource(address, typeTag); - return BigInt((accountResource.data as any).coin.value); - } // <:!:checkBalance -} diff --git a/m1/JavaScript-client/src/plugins/faucet_client.ts b/m1/JavaScript-client/src/plugins/faucet_client.ts deleted file mode 100644 index 4f854205f..000000000 --- a/m1/JavaScript-client/src/plugins/faucet_client.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/** Faucet creates and funds accounts. This is a thin wrapper around that. */ -import { AptosClient } from "../providers/aptos_client"; -import { OpenAPIConfig } from "../generated"; -import { AxiosHttpRequest } from "../generated/core/AxiosHttpRequest"; -import { HexString, MaybeHexString, DEFAULT_TXN_TIMEOUT_SEC } from "../utils"; - -/** - * Class for requsting tokens from faucet - */ -export class FaucetClient extends AptosClient { - faucetRequester: AxiosHttpRequest; - - /** - * Establishes a connection to Aptos node - * @param nodeUrl A url of the Aptos Node API endpoint - * @param faucetUrl A faucet url - * @param config An optional config for inner axios instance - * Detailed config description: {@link https://github.com/axios/axios#request-config} - */ - constructor(nodeUrl: string, faucetUrl: string, config?: Partial) { - super(nodeUrl, config); - - if (!faucetUrl) { - throw new Error("Faucet URL cannot be empty."); - } - // Build a requester configured to talk to the faucet. - this.faucetRequester = new AxiosHttpRequest({ - BASE: faucetUrl, - VERSION: config?.VERSION ?? "0.1.0", - WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false, - CREDENTIALS: config?.CREDENTIALS ?? "include", - TOKEN: config?.TOKEN, - USERNAME: config?.USERNAME, - PASSWORD: config?.PASSWORD, - HEADERS: config?.HEADERS, - ENCODE_PATH: config?.ENCODE_PATH, - }); - } - - /** - * This creates an account if it does not exist and mints the specified amount of - * coins into that account - * @param address Hex-encoded 16 bytes Aptos account address wich mints tokens - * @param amount Amount of tokens to mint - * @param timeoutSecs - * @returns Hashes of submitted transactions - */ - async fundAccount(address: MaybeHexString, amount: number, timeoutSecs = DEFAULT_TXN_TIMEOUT_SEC): Promise { - const tnxHashes = await this.faucetRequester.request>({ - method: "POST", - url: "/mint", - query: { - address: HexString.ensure(address).noPrefix(), - amount, - }, - }); - - const promises: Promise[] = []; - for (let i = 0; i < tnxHashes.length; i += 1) { - const tnxHash = tnxHashes[i]; - promises.push(this.waitForTransaction(tnxHash, { timeoutSecs })); - } - await Promise.all(promises); - return tnxHashes; - } -} diff --git a/m1/JavaScript-client/src/plugins/index.ts b/m1/JavaScript-client/src/plugins/index.ts deleted file mode 100644 index 00f561a26..000000000 --- a/m1/JavaScript-client/src/plugins/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./token_client"; -export * from "./aptos_token"; -export * from "./coin_client"; -export * from "./faucet_client"; diff --git a/m1/JavaScript-client/src/plugins/token_client.ts b/m1/JavaScript-client/src/plugins/token_client.ts deleted file mode 100644 index 507f143a9..000000000 --- a/m1/JavaScript-client/src/plugins/token_client.ts +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable max-len */ - -import { AptosAccount } from "../account/aptos_account"; -import { AptosClient, OptionalTransactionArgs } from "../providers/aptos_client"; -import * as TokenTypes from "../aptos_types/token_types"; -import * as Gen from "../generated/index"; -import { HexString, MaybeHexString } from "../utils"; -import { TransactionBuilder, TransactionBuilderRemoteABI, TxnBuilderTypes } from "../transaction_builder"; -import { MAX_U64_BIG_INT } from "../bcs/consts"; -import { AnyNumber, bcsToBytes, Bytes } from "../bcs"; -import { getPropertyValueRaw, PropertyMap } from "../utils/property_map_serde"; -import { Token, TokenData } from "../aptos_types/token_types"; - -/** - * Class for creating, minting and managing minting NFT collections and tokens - */ -export class TokenClient { - aptosClient: AptosClient; - - /** - * Creates new TokenClient instance - * - * @param aptosClient AptosClient instance - */ - constructor(aptosClient: AptosClient) { - this.aptosClient = aptosClient; - } - - /** - * Creates a new NFT collection within the specified account - * - * @param account AptosAccount where collection will be created - * @param name Collection name - * @param description Collection description - * @param uri URL to additional info about collection - * @param maxAmount Maximum number of `token_data` allowed within this collection - * @returns The hash of the transaction submitted to the API - */ - // :!:>createCollection - async createCollection( - account: AptosAccount, - name: string, - description: string, - uri: string, - maxAmount: AnyNumber = MAX_U64_BIG_INT, - extraArgs?: OptionalTransactionArgs, - ): Promise { - // <:!:createCollection - - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: account.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token::create_collection_script", - [], - [name, description, uri, maxAmount, [false, false, false]], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Creates a new NFT within the specified account - * - * @param account AptosAccount where token will be created - * @param collectionName Name of collection, that token belongs to - * @param name Token name - * @param description Token description - * @param supply Token supply - * @param uri URL to additional info about token - * @param max The maxium of tokens can be minted from this token - * @param royalty_payee_address the address to receive the royalty, the address can be a shared account address. - * @param royalty_points_denominator the denominator for calculating royalty - * @param royalty_points_numerator the numerator for calculating royalty - * @param property_keys the property keys for storing on-chain properties - * @param property_values the property values to be stored on-chain - * @param property_types the type of property values - * @returns The hash of the transaction submitted to the API - */ - // :!:>createToken - async createToken( - account: AptosAccount, - collectionName: string, - name: string, - description: string, - supply: number, - uri: string, - max: AnyNumber = MAX_U64_BIG_INT, - royalty_payee_address: MaybeHexString = account.address(), - royalty_points_denominator: number = 0, - royalty_points_numerator: number = 0, - property_keys: Array = [], - property_values: Array = [], - property_types: Array = [], - extraArgs?: OptionalTransactionArgs, - ): Promise { - // <:!:createToken - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: account.address(), ...extraArgs }); - - const rawTxn = await builder.build( - "0x3::token::create_token_script", - [], - [ - collectionName, - name, - description, - supply, - max, - uri, - royalty_payee_address, - royalty_points_denominator, - royalty_points_numerator, - [false, false, false, false, false], - property_keys, - getPropertyValueRaw(property_values, property_types), - property_types, - ], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Creates a new NFT within the specified account - * - * @param account AptosAccount where token will be created - * @param collectionName Name of collection, that token belongs to - * @param name Token name - * @param description Token description - * @param supply Token supply - * @param uri URL to additional info about token - * @param max The maxium of tokens can be minted from this token - * @param royalty_payee_address the address to receive the royalty, the address can be a shared account address. - * @param royalty_points_denominator the denominator for calculating royalty - * @param royalty_points_numerator the numerator for calculating royalty - * @param property_keys the property keys for storing on-chain properties - * @param property_values the property values to be stored on-chain - * @param property_types the type of property values - * @param mutability_config configs which field is mutable - * @returns The hash of the transaction submitted to the API - */ - // :!:>createToken - async createTokenWithMutabilityConfig( - account: AptosAccount, - collectionName: string, - name: string, - description: string, - supply: AnyNumber, - uri: string, - max: AnyNumber = MAX_U64_BIG_INT, - royalty_payee_address: MaybeHexString = account.address(), - royalty_points_denominator: AnyNumber = 0, - royalty_points_numerator: AnyNumber = 0, - property_keys: Array = [], - property_values: Array = [], - property_types: Array = [], - mutability_config: Array = [false, false, false, false, false], - extraArgs?: OptionalTransactionArgs, - ): Promise { - // <:!:createToken - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: account.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token::create_token_script", - [], - [ - collectionName, - name, - description, - supply, - max, - uri, - royalty_payee_address, - royalty_points_denominator, - royalty_points_numerator, - mutability_config, - property_keys, - property_values, - property_types, - ], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Transfers specified amount of tokens from account to receiver - * - * @param account AptosAccount where token from which tokens will be transfered - * @param receiver Hex-encoded 32 byte Aptos account address to which tokens will be transfered - * @param creator Hex-encoded 32 byte Aptos account address to which created tokens - * @param collectionName Name of collection where token is stored - * @param name Token name - * @param amount Amount of tokens which will be transfered - * @param property_version the version of token PropertyMap with a default value 0. - * @returns The hash of the transaction submitted to the API - */ - async offerToken( - account: AptosAccount, - receiver: MaybeHexString, - creator: MaybeHexString, - collectionName: string, - name: string, - amount: number, - property_version: number = 0, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: account.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token_transfers::offer_script", - [], - [receiver, creator, collectionName, name, property_version, amount], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Claims a token on specified account - * - * @param account AptosAccount which will claim token - * @param sender Hex-encoded 32 byte Aptos account address which holds a token - * @param creator Hex-encoded 32 byte Aptos account address which created a token - * @param collectionName Name of collection where token is stored - * @param name Token name - * @param property_version the version of token PropertyMap with a default value 0. - * @returns The hash of the transaction submitted to the API - */ - async claimToken( - account: AptosAccount, - sender: MaybeHexString, - creator: MaybeHexString, - collectionName: string, - name: string, - property_version: number = 0, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: account.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token_transfers::claim_script", - [], - [sender, creator, collectionName, name, property_version], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Removes a token from pending claims list - * - * @param account AptosAccount which will remove token from pending list - * @param receiver Hex-encoded 32 byte Aptos account address which had to claim token - * @param creator Hex-encoded 32 byte Aptos account address which created a token - * @param collectionName Name of collection where token is strored - * @param name Token name - * @param property_version the version of token PropertyMap with a default value 0. - * @returns The hash of the transaction submitted to the API - */ - async cancelTokenOffer( - account: AptosAccount, - receiver: MaybeHexString, - creator: MaybeHexString, - collectionName: string, - name: string, - property_version: number = 0, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: account.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token_transfers::cancel_offer_script", - [], - [receiver, creator, collectionName, name, property_version], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Directly transfer the specified amount of tokens from account to receiver - * using a single multi signature transaction. - * - * @param sender AptosAccount where token from which tokens will be transfered - * @param receiver Hex-encoded 32 byte Aptos account address to which tokens will be transfered - * @param creator Hex-encoded 32 byte Aptos account address to which created tokens - * @param collectionName Name of collection where token is stored - * @param name Token name - * @param amount Amount of tokens which will be transfered - * @param property_version the version of token PropertyMap with a default value 0. - * @returns The hash of the transaction submitted to the API - */ - async directTransferToken( - sender: AptosAccount, - receiver: AptosAccount, - creator: MaybeHexString, - collectionName: string, - name: string, - amount: AnyNumber, - propertyVersion: AnyNumber = 0, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: sender.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token::direct_transfer_script", - [], - [creator, collectionName, name, propertyVersion, amount], - ); - - const multiAgentTxn = new TxnBuilderTypes.MultiAgentRawTransaction(rawTxn, [ - TxnBuilderTypes.AccountAddress.fromHex(receiver.address()), - ]); - - const senderSignature = new TxnBuilderTypes.Ed25519Signature( - sender.signBuffer(TransactionBuilder.getSigningMessage(multiAgentTxn)).toUint8Array(), - ); - - const senderAuthenticator = new TxnBuilderTypes.AccountAuthenticatorEd25519( - new TxnBuilderTypes.Ed25519PublicKey(sender.signingKey.publicKey), - senderSignature, - ); - - const receiverSignature = new TxnBuilderTypes.Ed25519Signature( - receiver.signBuffer(TransactionBuilder.getSigningMessage(multiAgentTxn)).toUint8Array(), - ); - - const receiverAuthenticator = new TxnBuilderTypes.AccountAuthenticatorEd25519( - new TxnBuilderTypes.Ed25519PublicKey(receiver.signingKey.publicKey), - receiverSignature, - ); - - const multiAgentAuthenticator = new TxnBuilderTypes.TransactionAuthenticatorMultiAgent( - senderAuthenticator, - [TxnBuilderTypes.AccountAddress.fromHex(receiver.address())], // Secondary signer addresses - [receiverAuthenticator], // Secondary signer authenticators - ); - - const bcsTxn = bcsToBytes(new TxnBuilderTypes.SignedTransaction(rawTxn, multiAgentAuthenticator)); - - const transactionRes = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - - return transactionRes.hash; - } - - /** - * User opt-in or out direct transfer through a boolean flag - * - * @param sender AptosAccount where the token will be transferred - * @param optIn boolean value indicates user want to opt-in or out of direct transfer - * @returns The hash of the transaction submitted to the API - */ - async optInTokenTransfer(sender: AptosAccount, optIn: boolean, extraArgs?: OptionalTransactionArgs): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: sender.address(), ...extraArgs }); - const rawTxn = await builder.build("0x3::token::opt_in_direct_transfer", [], [optIn]); - const bcsTxn = AptosClient.generateBCSTransaction(sender, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Directly transfer token to a receiver. The receiver should have opted in to direct transfer - * - * @param sender AptosAccount where the token will be transferred - * @param creator address of the token creator - * @param collectionName Name of collection where token is stored - * @param name Token name - * @param property_version the version of token PropertyMap - * @param amount Amount of tokens which will be transfered - * @returns The hash of the transaction submitted to the API - */ - async transferWithOptIn( - sender: AptosAccount, - creator: MaybeHexString, - collectionName: string, - tokenName: string, - propertyVersion: AnyNumber, - receiver: MaybeHexString, - amount: AnyNumber, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: sender.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token::transfer_with_opt_in", - [], - [creator, collectionName, tokenName, propertyVersion, receiver, amount], - ); - const bcsTxn = AptosClient.generateBCSTransaction(sender, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * BurnToken by Creator - * - * @param creator creator of the token - * @param ownerAddress address of the token owner - * @param collectionName Name of collection where token is stored - * @param name Token name - * @param amount Amount of tokens which will be transfered - * @param property_version the version of token PropertyMap - * @returns The hash of the transaction submitted to the API - */ - async burnByCreator( - creator: AptosAccount, - ownerAddress: MaybeHexString, - collection: String, - name: String, - PropertyVersion: AnyNumber, - amount: AnyNumber, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: creator.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token::burn_by_creator", - [], - [ownerAddress, collection, name, PropertyVersion, amount], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(creator, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * BurnToken by Owner - * - * @param owner creator of the token - * @param creatorAddress address of the token creator - * @param collectionName Name of collection where token is stored - * @param name Token name - * @param amount Amount of tokens which will be transfered - * @param property_version the version of token PropertyMap - * @returns The hash of the transaction submitted to the API - */ - async burnByOwner( - owner: AptosAccount, - creatorAddress: MaybeHexString, - collection: String, - name: String, - PropertyVersion: AnyNumber, - amount: AnyNumber, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: owner.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token::burn", - [], - [creatorAddress, collection, name, PropertyVersion, amount], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(owner, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * creator mutates the properties of the tokens - * - * @param account AptosAccount who modifies the token properties - * @param tokenOwner the address of account owning the token - * @param creator the creator of the token - * @param collection_name the name of the token collection - * @param tokenName the name of created token - * @param propertyVersion the property_version of the token to be modified - * @param amount the number of tokens to be modified - * - * @returns The hash of the transaction submitted to the API - */ - async mutateTokenProperties( - account: AptosAccount, - tokenOwner: HexString, - creator: HexString, - collection_name: string, - tokenName: string, - propertyVersion: AnyNumber, - amount: AnyNumber, - keys: Array, - values: Array, - types: Array, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const builder = new TransactionBuilderRemoteABI(this.aptosClient, { sender: account.address(), ...extraArgs }); - const rawTxn = await builder.build( - "0x3::token::mutate_token_properties", - [], - [tokenOwner, creator, collection_name, tokenName, propertyVersion, amount, keys, values, types], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account, rawTxn); - const pendingTransaction = await this.aptosClient.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - } - - /** - * Queries collection data - * @param creator Hex-encoded 32 byte Aptos account address which created a collection - * @param collectionName Collection name - * @returns Collection data in below format - * ``` - * Collection { - * // Describes the collection - * description: string, - * // Unique name within this creators account for this collection - * name: string, - * // URL for additional information/media - * uri: string, - * // Total number of distinct Tokens tracked by the collection - * count: number, - * // Optional maximum number of tokens allowed within this collections - * maximum: number - * } - * ``` - */ - async getCollectionData(creator: MaybeHexString, collectionName: string): Promise { - const resources = await this.aptosClient.getAccountResources(creator); - const accountResource: { type: Gen.MoveStructTag; data: any } = resources.find( - (r) => r.type === "0x3::token::Collections", - )!; - const { handle }: { handle: string } = accountResource.data.collection_data; - const getCollectionTableItemRequest: Gen.TableItemRequest = { - key_type: "0x1::string::String", - value_type: "0x3::token::CollectionData", - key: collectionName, - }; - - const collectionTable = await this.aptosClient.getTableItem(handle, getCollectionTableItemRequest); - return collectionTable; - } - - /** - * Queries token data from collection - * - * @param creator Hex-encoded 32 byte Aptos account address which created a token - * @param collectionName Name of collection, which holds a token - * @param tokenName Token name - * @returns Token data in below format - * ``` - * TokenData { - * // Unique name within this creators account for this Token's collection - * collection: string; - * // Describes this Token - * description: string; - * // The name of this Token - * name: string; - * // Optional maximum number of this type of Token. - * maximum: number; - * // Total number of this type of Token - * supply: number; - * /// URL for additional information / media - * uri: string; - * } - * ``` - */ - // :!:>getTokenData - async getTokenData( - creator: MaybeHexString, - collectionName: string, - tokenName: string, - ): Promise { - const creatorHex = creator instanceof HexString ? creator.hex() : creator; - const collection: { type: Gen.MoveStructTag; data: any } = await this.aptosClient.getAccountResource( - creatorHex, - "0x3::token::Collections", - ); - const { handle } = collection.data.token_data; - const tokenDataId = { - creator: creatorHex, - collection: collectionName, - name: tokenName, - }; - - const getTokenTableItemRequest: Gen.TableItemRequest = { - key_type: "0x3::token::TokenDataId", - value_type: "0x3::token::TokenData", - key: tokenDataId, - }; - - // We know the response will be a struct containing TokenData, hence the - // implicit cast. - const rawTokenData = await this.aptosClient.getTableItem(handle, getTokenTableItemRequest); - return new TokenData( - rawTokenData.collection, - rawTokenData.description, - rawTokenData.name, - rawTokenData.maximum, - rawTokenData.supply, - rawTokenData.uri, - rawTokenData.default_properties, - rawTokenData.mutability_config, - ); - } // <:!:getTokenData - - /** - * Queries token balance for the token creator - */ - async getToken( - creator: MaybeHexString, - collectionName: string, - tokenName: string, - property_version: string = "0", - ): Promise { - const tokenDataId: TokenTypes.TokenDataId = { - creator: creator instanceof HexString ? creator.hex() : creator, - collection: collectionName, - name: tokenName, - }; - return this.getTokenForAccount(creator, { - token_data_id: tokenDataId, - property_version, - }); - } - - /** - * Queries token balance for a token account - * @param account Hex-encoded 32 byte Aptos account address which created a token - * @param tokenId token id - * - * TODO: Update this: - * @example - * ``` - * { - * creator: '0x1', - * collection: 'Some collection', - * name: 'Awesome token' - * } - * ``` - * @returns Token object in below format - * ``` - * Token { - * id: TokenId; - * value: number; - * } - * ``` - */ - async getTokenForAccount(account: MaybeHexString, tokenId: TokenTypes.TokenId): Promise { - const tokenStore: { type: Gen.MoveStructTag; data: any } = await this.aptosClient.getAccountResource( - account instanceof HexString ? account.hex() : account, - "0x3::token::TokenStore", - ); - const { handle } = tokenStore.data.tokens; - - const getTokenTableItemRequest: Gen.TableItemRequest = { - key_type: "0x3::token::TokenId", - value_type: "0x3::token::Token", - key: tokenId, - }; - - try { - const rawToken = await this.aptosClient.getTableItem(handle, getTokenTableItemRequest); - return new Token(rawToken.id, rawToken.amount, rawToken.token_properties); - } catch (error: any) { - if (error?.status === 404) { - return { - id: tokenId, - amount: "0", - token_properties: new PropertyMap(), - }; - } - return error; - } - } -} diff --git a/m1/JavaScript-client/src/providers/aptos_client.ts b/m1/JavaScript-client/src/providers/aptos_client.ts deleted file mode 100644 index 935e977ae..000000000 --- a/m1/JavaScript-client/src/providers/aptos_client.ts +++ /dev/null @@ -1,1001 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { - clear, - DEFAULT_TXN_EXP_SEC_FROM_NOW, - DEFAULT_MAX_GAS_AMOUNT, - DEFAULT_TXN_TIMEOUT_SEC, - fixNodeUrl, - HexString, - paginateWithCursor, - MaybeHexString, - Memoize, - sleep, - APTOS_COIN, -} from "../utils"; -import { AptosAccount } from "../account/aptos_account"; -import * as Gen from "../generated/index"; -import { - TxnBuilderTypes, - TransactionBuilderEd25519, - TransactionBuilderRemoteABI, - RemoteABIBuilderConfig, - TransactionBuilderMultiEd25519, -} from "../transaction_builder"; -import { - bcsSerializeBytes, - bcsSerializeU8, - bcsToBytes, - Bytes, - Seq, - Serializer, - serializeVector, - Uint64, - AnyNumber, -} from "../bcs"; -import { Ed25519PublicKey, MultiEd25519PublicKey } from "../aptos_types"; - -export interface OptionalTransactionArgs { - maxGasAmount?: Uint64; - gasUnitPrice?: Uint64; - expireTimestamp?: Uint64; -} - -interface PaginationArgs { - start?: AnyNumber; - limit?: number; -} - -/** - * Provides methods for retrieving data from Aptos node. - * For more detailed API specification see {@link https://fullnode.devnet.aptoslabs.com/v1/spec} - */ -export class AptosClient { - client: Gen.AptosGeneratedClient; - - readonly nodeUrl: string; - - /** - * Build a client configured to connect to an Aptos node at the given URL. - * - * Note: If you forget to append `/v1` to the URL, the client constructor - * will automatically append it. If you don't want this URL processing to - * take place, set doNotFixNodeUrl to true. - * - * @param nodeUrl URL of the Aptos Node API endpoint. - * @param config Additional configuration options for the generated Axios client. - */ - constructor(nodeUrl: string, config?: Partial, doNotFixNodeUrl: boolean = false) { - if (!nodeUrl) { - throw new Error("Node URL cannot be empty."); - } - const conf = config === undefined || config === null ? {} : { ...config }; - - if (doNotFixNodeUrl) { - this.nodeUrl = nodeUrl; - } else { - this.nodeUrl = fixNodeUrl(nodeUrl); - } - conf.BASE = this.nodeUrl; - - // Do not carry cookies when `WITH_CREDENTIALS` is explicitly set to `false`. By default, cookies will be sent - if (config?.WITH_CREDENTIALS === false) { - conf.WITH_CREDENTIALS = false; - } else { - conf.WITH_CREDENTIALS = true; - } - this.client = new Gen.AptosGeneratedClient(conf); - } - - /** - * Queries an Aptos account by address - * @param accountAddress Hex-encoded 32 byte Aptos account address - * @returns Core account resource, used for identifying account and transaction execution - * @example An example of the returned account - * ``` - * { - * sequence_number: "1", - * authentication_key: "0x5307b5f4bc67829097a8ba9b43dba3b88261eeccd1f709d9bde240fc100fbb69" - * } - * ``` - */ - @parseApiError - async getAccount(accountAddress: MaybeHexString): Promise { - return this.client.accounts.getAccount(HexString.ensure(accountAddress).hex()); - } - - /** - * Queries transactions sent by given account - * @param accountAddress Hex-encoded 32 byte Aptos account address - * @param query Optional pagination object - * @param query.start The sequence number of the start transaction of the page. Default is 0. - * @param query.limit The max number of transactions should be returned for the page. Default is 25. - * @returns An array of on-chain transactions, sent by account - */ - @parseApiError - async getAccountTransactions(accountAddress: MaybeHexString, query?: PaginationArgs): Promise { - return this.client.transactions.getAccountTransactions( - HexString.ensure(accountAddress).hex(), - query?.start?.toString(), - query?.limit, - ); - } - - /** - * Queries modules associated with given account - * - * Note: In order to get all account modules, this function may call the API - * multiple times as it paginates. - * - * @param accountAddress Hex-encoded 32 byte Aptos account address - * @param query.ledgerVersion Specifies ledger version of transactions. By default latest version will be used - * @returns Account modules array for a specific ledger version. - * Module is represented by MoveModule interface. It contains module `bytecode` and `abi`, - * which is JSON representation of a module - */ - @parseApiError - async getAccountModules( - accountAddress: MaybeHexString, - query?: { ledgerVersion?: AnyNumber }, - ): Promise { - // Note: This function does not expose a `limit` parameter because it might - // be ambiguous how this is being used. Is it being passed to getAccountModules - // to limit the number of items per response, or does it limit the total output - // of this function? We avoid this confusion by not exposing the parameter at all. - const f = this.client.accounts.getAccountModules.bind({ httpRequest: this.client.request }); - const out = await paginateWithCursor(f, accountAddress, 1000, query); - return out; - } - - /** - * Queries module associated with given account by module name - * - * Note: In order to get all account resources, this function may call the API - * multiple times as it paginates. - * - * @param accountAddress Hex-encoded 32 byte Aptos account address - * @param moduleName The name of the module - * @param query.ledgerVersion Specifies ledger version of transactions. By default latest version will be used - * @returns Specified module. - * Module is represented by MoveModule interface. It contains module `bytecode` and `abi`, - * which JSON representation of a module - */ - @parseApiError - async getAccountModule( - accountAddress: MaybeHexString, - moduleName: string, - query?: { ledgerVersion?: AnyNumber }, - ): Promise { - return this.client.accounts.getAccountModule( - HexString.ensure(accountAddress).hex(), - moduleName, - query?.ledgerVersion?.toString(), - ); - } - - /** - * Queries all resources associated with given account - * @param accountAddress Hex-encoded 32 byte Aptos account address - * @param query.ledgerVersion Specifies ledger version of transactions. By default latest version will be used - * @returns Account resources for a specific ledger version - */ - @parseApiError - async getAccountResources( - accountAddress: MaybeHexString, - query?: { ledgerVersion?: AnyNumber }, - ): Promise { - const f = this.client.accounts.getAccountResources.bind({ httpRequest: this.client.request }); - const out = await paginateWithCursor(f, accountAddress, 9999, query); - return out; - } - - /** - * Queries resource associated with given account by resource type - * @param accountAddress Hex-encoded 32 byte Aptos account address - * @param resourceType String representation of an on-chain Move struct type - * @param query.ledgerVersion Specifies ledger version of transactions. By default latest version will be used - * @returns Account resource of specified type and ledger version - * @example An example of an account resource - * ``` - * { - * type: "0x1::aptos_coin::AptosCoin", - * data: { value: 6 } - * } - * ``` - */ - @parseApiError - async getAccountResource( - accountAddress: MaybeHexString, - resourceType: Gen.MoveStructTag, - query?: { ledgerVersion?: AnyNumber }, - ): Promise { - return this.client.accounts.getAccountResource( - HexString.ensure(accountAddress).hex(), - resourceType, - query?.ledgerVersion?.toString(), - ); - } - - /** Generates a signed transaction that can be submitted to the chain for execution. */ - static generateBCSTransaction(accountFrom: AptosAccount, rawTxn: TxnBuilderTypes.RawTransaction): Uint8Array { - const txnBuilder = new TransactionBuilderEd25519((signingMessage: TxnBuilderTypes.SigningMessage) => { - // @ts-ignore - const sigHexStr = accountFrom.signBuffer(signingMessage); - return new TxnBuilderTypes.Ed25519Signature(sigHexStr.toUint8Array()); - }, accountFrom.pubKey().toUint8Array()); - - return txnBuilder.sign(rawTxn); - } - - /** - * Note: Unless you have a specific reason for using this, it'll probably be simpler - * to use `simulateTransaction`. - * - * Generates a BCS transaction that can be submitted to the chain for simulation. - * - * @param accountFrom The account that will be used to send the transaction - * for simulation. - * @param rawTxn The raw transaction to be simulated, likely created by calling - * the `generateTransaction` function. - * @returns The BCS encoded signed transaction, which you should then pass into - * the `submitBCSSimulation` function. - */ - static generateBCSSimulation(accountFrom: AptosAccount, rawTxn: TxnBuilderTypes.RawTransaction): Uint8Array { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const txnBuilder = new TransactionBuilderEd25519((_signingMessage: TxnBuilderTypes.SigningMessage) => { - // @ts-ignore - const invalidSigBytes = new Uint8Array(64); - return new TxnBuilderTypes.Ed25519Signature(invalidSigBytes); - }, accountFrom.pubKey().toUint8Array()); - - return txnBuilder.sign(rawTxn); - } - - /** Generates an entry function transaction request that can be submitted to produce a raw transaction that - * can be signed, which upon being signed can be submitted to the blockchain - * This function fetches the remote ABI and uses it to serialized the data, therefore - * users don't need to handle serialization by themselves. - * @param sender Hex-encoded 32 byte Aptos account address of transaction sender - * @param payload Entry function transaction payload type - * @param options Options allow to overwrite default transaction options. - * @returns A raw transaction object - */ - async generateTransaction( - sender: MaybeHexString, - payload: Gen.EntryFunctionPayload, - options?: Partial, - ): Promise { - const config: RemoteABIBuilderConfig = { sender }; - if (options?.sequence_number) { - config.sequenceNumber = options.sequence_number; - } - - if (options?.gas_unit_price) { - config.gasUnitPrice = options.gas_unit_price; - } - - if (options?.max_gas_amount) { - config.maxGasAmount = options.max_gas_amount; - } - - if (options?.expiration_timestamp_secs) { - const timestamp = Number.parseInt(options.expiration_timestamp_secs, 10); - config.expSecFromNow = timestamp - Math.floor(Date.now() / 1000); - } - - const builder = new TransactionBuilderRemoteABI(this, config); - return builder.build(payload.function, payload.type_arguments, payload.arguments); - } - - /** Converts a transaction request produced by `generateTransaction` into a properly - * signed transaction, which can then be submitted to the blockchain - * @param accountFrom AptosAccount of transaction sender - * @param rawTransaction A raw transaction generated by `generateTransaction` method - * @returns A transaction, signed with sender account - */ - // eslint-disable-next-line class-methods-use-this - async signTransaction( - accountFrom: AptosAccount, - rawTransaction: TxnBuilderTypes.RawTransaction, - ): Promise { - return Promise.resolve(AptosClient.generateBCSTransaction(accountFrom, rawTransaction)); - } - - /** - * Event types are globally identifiable by an account `address` and - * monotonically increasing `creation_number`, one per event type emitted - * to the given account. This API returns events corresponding to that - * that event type. - * @param address Hex-encoded 32 byte Aptos account, with or without a `0x` prefix, - * for which events are queried. This refers to the account that events were emitted - * to, not the account hosting the move module that emits that event type. - * @param creationNumber Creation number corresponding to the event type. - * @returns Array of events assotiated with the given account and creation number. - */ - @parseApiError - async getEventsByCreationNumber( - address: MaybeHexString, - creationNumber: AnyNumber | string, - query?: PaginationArgs, - ): Promise { - return this.client.events.getEventsByCreationNumber( - HexString.ensure(address).hex(), - creationNumber.toString(), - query?.start?.toString(), - query?.limit, - ); - } - - /** - * This API uses the given account `address`, `eventHandle`, and `fieldName` - * to build a key that can globally identify an event types. It then uses this - * key to return events emitted to the given account matching that event type. - * @param address Hex-encoded 32 byte Aptos account, with or without a `0x` prefix, - * for which events are queried. This refers to the account that events were emitted - * to, not the account hosting the move module that emits that event type. - * @param eventHandleStruct String representation of an on-chain Move struct type. - * (e.g. `0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>`) - * @param fieldName The field name of the EventHandle in the struct - * @param query Optional query object - * @param query.start The start sequence number in the EVENT STREAM, defaulting to the latest event. - * The events are returned in the reverse order of sequence number - * @param query.limit The number of events to be returned. The default is 25. - * @returns Array of events - */ - @parseApiError - async getEventsByEventHandle( - address: MaybeHexString, - eventHandleStruct: Gen.MoveStructTag, - fieldName: string, - query?: PaginationArgs, - ): Promise { - return this.client.events.getEventsByEventHandle( - HexString.ensure(address).hex(), - eventHandleStruct, - fieldName, - query?.start?.toString(), - query?.limit, - ); - } - - /** - * Submits a signed transaction to the transaction endpoint. - * @param signedTxn A transaction, signed by `signTransaction` method - * @returns Transaction that is accepted and submitted to mempool - */ - async submitTransaction(signedTxn: Uint8Array): Promise { - return this.submitSignedBCSTransaction(signedTxn); - } - - /** - * Generates and submits a transaction to the transaction simulation - * endpoint. For this we generate a transaction with a fake signature. - * - * @param accountOrPubkey The sender or sender's public key. When private key is available, `AptosAccount` instance - * can be used to send the transaction for simulation. If private key is not available, sender's public key can be - * used to send the transaction for simulation. - * @param rawTransaction The raw transaction to be simulated, likely created - * by calling the `generateTransaction` function. - * @param query.estimateGasUnitPrice If set to true, the gas unit price in the - * transaction will be ignored and the estimated value will be used. - * @param query.estimateMaxGasAmount If set to true, the max gas value in the - * transaction will be ignored and the maximum possible gas will be used. - * @param query.estimatePrioritizedGasUnitPrice If set to true, the transaction will use a higher price than the - * original estimate. - * @returns The BCS encoded signed transaction, which you should then provide - * - */ - async simulateTransaction( - accountOrPubkey: AptosAccount | Ed25519PublicKey | MultiEd25519PublicKey, - rawTransaction: TxnBuilderTypes.RawTransaction, - query?: { - estimateGasUnitPrice?: boolean; - estimateMaxGasAmount?: boolean; - estimatePrioritizedGasUnitPrice: boolean; - }, - ): Promise { - let signedTxn: Uint8Array; - - if (accountOrPubkey instanceof AptosAccount) { - signedTxn = AptosClient.generateBCSSimulation(accountOrPubkey, rawTransaction); - } else if (accountOrPubkey instanceof MultiEd25519PublicKey) { - const txnBuilder = new TransactionBuilderMultiEd25519(() => { - const { threshold } = accountOrPubkey; - const bits: Seq = []; - const signatures: TxnBuilderTypes.Ed25519Signature[] = []; - for (let i = 0; i < threshold; i += 1) { - bits.push(i); - signatures.push(new TxnBuilderTypes.Ed25519Signature(new Uint8Array(64))); - } - const bitmap = TxnBuilderTypes.MultiEd25519Signature.createBitmap(bits); - return new TxnBuilderTypes.MultiEd25519Signature(signatures, bitmap); - }, accountOrPubkey); - - signedTxn = txnBuilder.sign(rawTransaction); - } else { - const txnBuilder = new TransactionBuilderEd25519(() => { - const invalidSigBytes = new Uint8Array(64); - return new TxnBuilderTypes.Ed25519Signature(invalidSigBytes); - }, accountOrPubkey.toBytes()); - - signedTxn = txnBuilder.sign(rawTransaction); - } - return this.submitBCSSimulation(signedTxn, query); - } - - /** - * Submits a signed transaction to the endpoint that takes BCS payload - * - * @param signedTxn A BCS transaction representation - * @returns Transaction that is accepted and submitted to mempool - */ - @parseApiError - async submitSignedBCSTransaction(signedTxn: Uint8Array): Promise { - // Need to construct a customized post request for transactions in BCS payload - return this.client.request.request({ - url: "/transactions", - method: "POST", - body: signedTxn, - mediaType: "application/x.aptos.signed_transaction+bcs", - }); - } - - /** - * Submits the BCS serialization of a signed transaction to the simulation endpoint. - * - * @param bcsBody The output of `generateBCSSimulation`. - * @param query?.estimateGasUnitPrice If set to true, the gas unit price in the - * transaction will be ignored and the estimated value will be used. - * @param query?.estimateMaxGasAmount If set to true, the max gas value in the - * transaction will be ignored and the maximum possible gas will be used. - * @param query?.estimatePrioritizedGasUnitPrice If set to true, the transaction will use a higher price than the - * original estimate. - * @returns Simulation result in the form of UserTransaction. - */ - @parseApiError - async submitBCSSimulation( - bcsBody: Uint8Array, - query?: { - estimateGasUnitPrice?: boolean; - estimateMaxGasAmount?: boolean; - estimatePrioritizedGasUnitPrice?: boolean; - }, - ): Promise { - // Need to construct a customized post request for transactions in BCS payload. - const queryParams = { - estimate_gas_unit_price: query?.estimateGasUnitPrice ?? false, - estimate_max_gas_amount: query?.estimateMaxGasAmount ?? false, - estimate_prioritized_gas_unit_price: query?.estimatePrioritizedGasUnitPrice ?? false, - }; - return this.client.request.request({ - url: "/transactions/simulate", - query: queryParams, - method: "POST", - body: bcsBody, - mediaType: "application/x.aptos.signed_transaction+bcs", - }); - } - - /** - * Queries on-chain transactions. This function will not return pending - * transactions. For that, use `getTransactionsByHash`. - * - * @param query Optional pagination object - * @param query.start The start transaction version of the page. Default is the latest ledger version - * @param query.limit The max number of transactions should be returned for the page. Default is 25 - * @returns Array of on-chain transactions - */ - @parseApiError - async getTransactions(query?: PaginationArgs): Promise { - return this.client.transactions.getTransactions(query?.start?.toString(), query?.limit); - } - - /** - * @param txnHash - Transaction hash should be hex-encoded bytes string with 0x prefix. - * @returns Transaction from mempool (pending) or on-chain (committed) transaction - */ - @parseApiError - async getTransactionByHash(txnHash: string): Promise { - return this.client.transactions.getTransactionByHash(txnHash); - } - - /** - * @param txnVersion - Transaction version is an uint64 number. - * @returns On-chain transaction. Only on-chain transactions have versions, so this - * function cannot be used to query pending transactions. - */ - @parseApiError - async getTransactionByVersion(txnVersion: AnyNumber): Promise { - return this.client.transactions.getTransactionByVersion(txnVersion.toString()); - } - - /** - * Defines if specified transaction is currently in pending state - * @param txnHash A hash of transaction - * - * To create a transaction hash: - * - * 1. Create hash message bytes: "Aptos::Transaction" bytes + BCS bytes of Transaction. - * 2. Apply hash algorithm SHA3-256 to the hash message bytes. - * 3. Hex-encode the hash bytes with 0x prefix. - * - * @returns `true` if transaction is in pending state and `false` otherwise - */ - async transactionPending(txnHash: string): Promise { - try { - const response = await this.client.transactions.getTransactionByHash(txnHash); - return response.type === "pending_transaction"; - } catch (e: any) { - if (e?.status === 404) { - return true; - } - throw e; - } - } - - /** - * Wait for a transaction to move past pending state. - * - * There are 4 possible outcomes: - * 1. Transaction is processed and successfully committed to the blockchain. - * 2. Transaction is rejected for some reason, and is therefore not committed - * to the blockchain. - * 3. Transaction is committed but execution failed, meaning no changes were - * written to the blockchain state. - * 4. Transaction is not processed within the specified timeout. - * - * In case 1, this function resolves with the transaction response returned - * by the API. - * - * In case 2, the function will throw an ApiError, likely with an HTTP status - * code indicating some problem with the request (e.g. 400). - * - * In case 3, if `checkSuccess` is false (the default), this function returns - * the transaction response just like in case 1, in which the `success` field - * will be false. If `checkSuccess` is true, it will instead throw a - * FailedTransactionError. - * - * In case 4, this function throws a WaitForTransactionError. - * - * @param txnHash The hash of a transaction previously submitted to the blockchain. - * @param extraArgs.timeoutSecs Timeout in seconds. Defaults to 20 seconds. - * @param extraArgs.checkSuccess See above. Defaults to false. - * @returns See above. - * - * @example - * ``` - * const rawTransaction = await this.generateRawTransaction(sender.address(), payload, extraArgs); - * const bcsTxn = AptosClient.generateBCSTransaction(sender, rawTransaction); - * const pendingTransaction = await this.submitSignedBCSTransaction(bcsTxn); - * const transasction = await this.aptosClient.waitForTransactionWithResult(pendingTransaction.hash); - * ``` - */ - async waitForTransactionWithResult( - txnHash: string, - extraArgs?: { timeoutSecs?: number; checkSuccess?: boolean }, - ): Promise { - const timeoutSecs = extraArgs?.timeoutSecs ?? DEFAULT_TXN_TIMEOUT_SEC; - const checkSuccess = extraArgs?.checkSuccess ?? false; - - let isPending = true; - let count = 0; - let lastTxn: Gen.Transaction | undefined; - while (isPending) { - if (count >= timeoutSecs) { - break; - } - try { - // eslint-disable-next-line no-await-in-loop - lastTxn = await this.client.transactions.getTransactionByHash(txnHash); - isPending = lastTxn.type === "pending_transaction"; - if (!isPending) { - break; - } - } catch (e) { - // In short, this means we will retry if it was an ApiError and the code was 404 or 5xx. - const isApiError = e instanceof Gen.ApiError; - const isRequestError = isApiError && e.status !== 404 && e.status >= 400 && e.status < 500; - if (!isApiError || isRequestError) { - throw e; - } - } - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - count += 1; - } - - // There is a chance that lastTxn is still undefined. Let's throw some error here - if (lastTxn === undefined) { - throw new Error(`Waiting for transaction ${txnHash} failed`); - } - - if (isPending) { - throw new WaitForTransactionError( - `Waiting for transaction ${txnHash} timed out after ${timeoutSecs} seconds`, - lastTxn, - ); - } - if (!checkSuccess) { - return lastTxn; - } - if (!(lastTxn as any)?.success) { - throw new FailedTransactionError( - `Transaction ${txnHash} committed to the blockchain but execution failed`, - lastTxn, - ); - } - return lastTxn; - } - - /** - * This function works the same as `waitForTransactionWithResult` except it - * doesn't return the transaction in those cases, it returns nothing. For - * more information, see the documentation for `waitForTransactionWithResult`. - */ - async waitForTransaction( - txnHash: string, - extraArgs?: { timeoutSecs?: number; checkSuccess?: boolean }, - ): Promise { - await this.waitForTransactionWithResult(txnHash, extraArgs); - } - - /** - * Queries the latest ledger information - * @returns Latest ledger information - * @example Example of returned data - * ``` - * { - * chain_id: 15, - * epoch: 6, - * ledgerVersion: "2235883", - * ledger_timestamp:"1654580922321826" - * } - * ``` - */ - @parseApiError - async getLedgerInfo(): Promise { - return this.client.general.getLedgerInfo(); - } - - /** - * @returns Current chain id - */ - @Memoize() - async getChainId(): Promise { - const result = await this.getLedgerInfo(); - return result.chain_id; - } - - /** - * Gets a table item for a table identified by the handle and the key for the item. - * Key and value types need to be passed in to help with key serialization and value deserialization. - * @param handle A pointer to where that table is stored - * @param data Object, that describes table item - * @param data.key_type Move type of table key (e.g. `vector`) - * @param data.value_type Move type of table value (e.g. `u64`) - * @param data.key Value of table key - * @returns Table item value rendered in JSON - */ - @parseApiError - async getTableItem(handle: string, data: Gen.TableItemRequest, query?: { ledgerVersion?: AnyNumber }): Promise { - const tableItem = await this.client.tables.getTableItem(handle, data, query?.ledgerVersion?.toString()); - return tableItem; - } - - /** - * Generates a raw transaction out of a transaction payload - * @param accountFrom - * @param payload - * @param extraArgs - * @returns A raw transaction object - */ - async generateRawTransaction( - accountFrom: HexString, - payload: TxnBuilderTypes.TransactionPayload, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const [{ sequence_number: sequenceNumber }, chainId, { gas_estimate: gasEstimate }] = await Promise.all([ - this.getAccount(accountFrom), - this.getChainId(), - extraArgs?.gasUnitPrice ? Promise.resolve({ gas_estimate: extraArgs.gasUnitPrice }) : this.estimateGasPrice(), - ]); - - const { maxGasAmount, gasUnitPrice, expireTimestamp } = { - maxGasAmount: BigInt(DEFAULT_MAX_GAS_AMOUNT), - gasUnitPrice: BigInt(gasEstimate), - expireTimestamp: BigInt(Math.floor(Date.now() / 1000) + DEFAULT_TXN_EXP_SEC_FROM_NOW), - ...extraArgs, - }; - - return new TxnBuilderTypes.RawTransaction( - TxnBuilderTypes.AccountAddress.fromHex(accountFrom), - BigInt(sequenceNumber), - payload, - maxGasAmount, - gasUnitPrice, - expireTimestamp, - new TxnBuilderTypes.ChainId(chainId), - ); - } - - /** - * Helper for generating, signing, and submitting a transaction. - * - * @param sender AptosAccount of transaction sender. - * @param payload Transaction payload. - * @param extraArgs Extra args for building the transaction payload. - * @returns The transaction response from the API. - */ - async generateSignSubmitTransaction( - sender: AptosAccount, - payload: TxnBuilderTypes.TransactionPayload, - extraArgs?: OptionalTransactionArgs, - ): Promise { - // :!:>generateSignSubmitTransactionInner - const rawTransaction = await this.generateRawTransaction(sender.address(), payload, extraArgs); - const bcsTxn = AptosClient.generateBCSTransaction(sender, rawTransaction); - const pendingTransaction = await this.submitSignedBCSTransaction(bcsTxn); - return pendingTransaction.hash; - // <:!:generateSignSubmitTransactionInner - } - - /** - * Publishes a move package. `packageMetadata` and `modules` can be generated with command - * `aptos move compile --save-metadata [ --included-artifacts=<...> ]`. - * @param sender - * @param packageMetadata package metadata bytes - * @param modules bytecodes of modules - * @param extraArgs - * @returns Transaction hash - */ - async publishPackage( - sender: AptosAccount, - packageMetadata: Bytes, - modules: Seq, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const codeSerializer = new Serializer(); - serializeVector(modules, codeSerializer); - - const payload = new TxnBuilderTypes.TransactionPayloadEntryFunction( - TxnBuilderTypes.EntryFunction.natural( - "0x1::code", - "publish_package_txn", - [], - [bcsSerializeBytes(packageMetadata), codeSerializer.getBytes()], - ), - ); - - return this.generateSignSubmitTransaction(sender, payload, extraArgs); - } - - /** - * Helper for generating, submitting, and waiting for a transaction, and then - * checking whether it was committed successfully. Under the hood this is just - * `generateSignSubmitTransaction` and then `waitForTransactionWithResult`, see - * those for information about the return / error semantics of this function. - */ - async generateSignSubmitWaitForTransaction( - sender: AptosAccount, - payload: TxnBuilderTypes.TransactionPayload, - extraArgs?: OptionalTransactionArgs & { - checkSuccess?: boolean; - timeoutSecs?: number; - }, - ): Promise { - const txnHash = await this.generateSignSubmitTransaction(sender, payload, extraArgs); - return this.waitForTransactionWithResult(txnHash, extraArgs); - } - - @parseApiError - @Memoize({ - ttlMs: 5 * 60 * 1000, // cache result for 5min - tags: ["gas_estimates"], - }) - async estimateGasPrice(): Promise { - return this.client.transactions.estimateGasPrice(); - } - - @parseApiError - async estimateMaxGasAmount(forAccount: MaybeHexString): Promise { - // Only Aptos utility coin is accepted as gas - const typeTag = `0x1::coin::CoinStore<${APTOS_COIN}>`; - - const [{ gas_estimate: gasUnitPrice }, resources] = await Promise.all([ - this.estimateGasPrice(), - this.getAccountResources(forAccount), - ]); - - const accountResource = resources.find((r) => r.type === typeTag); - const balance = BigInt((accountResource!.data as any).coin.value); - return balance / BigInt(gasUnitPrice); - } - - /** - * Rotate an account's auth key. After rotation, only the new private key can be used to sign txns for - * the account. - * WARNING: You must create a new instance of AptosAccount after using this function. - * @param forAccount Account of which the auth key will be rotated - * @param toPrivateKeyBytes New private key - * @param extraArgs Extra args for building the transaction payload. - * @returns PendingTransaction - */ - async rotateAuthKeyEd25519( - forAccount: AptosAccount, - toPrivateKeyBytes: Uint8Array, - extraArgs?: OptionalTransactionArgs, - ): Promise { - const { sequence_number: sequenceNumber, authentication_key: authKey } = await this.getAccount( - forAccount.address(), - ); - - const helperAccount = new AptosAccount(toPrivateKeyBytes); - - const challenge = new TxnBuilderTypes.RotationProofChallenge( - TxnBuilderTypes.AccountAddress.CORE_CODE_ADDRESS, - "account", - "RotationProofChallenge", - BigInt(sequenceNumber), - TxnBuilderTypes.AccountAddress.fromHex(forAccount.address()), - new TxnBuilderTypes.AccountAddress(new HexString(authKey).toUint8Array()), - helperAccount.pubKey().toUint8Array(), - ); - - const challengeHex = HexString.fromUint8Array(bcsToBytes(challenge)); - - const proofSignedByCurrentPrivateKey = forAccount.signHexString(challengeHex); - - const proofSignedByNewPrivateKey = helperAccount.signHexString(challengeHex); - - const payload = new TxnBuilderTypes.TransactionPayloadEntryFunction( - TxnBuilderTypes.EntryFunction.natural( - "0x1::account", - "rotate_authentication_key", - [], - [ - bcsSerializeU8(0), // ed25519 scheme - bcsSerializeBytes(forAccount.pubKey().toUint8Array()), - bcsSerializeU8(0), // ed25519 scheme - bcsSerializeBytes(helperAccount.pubKey().toUint8Array()), - bcsSerializeBytes(proofSignedByCurrentPrivateKey.toUint8Array()), - bcsSerializeBytes(proofSignedByNewPrivateKey.toUint8Array()), - ], - ), - ); - - const rawTransaction = await this.generateRawTransaction(forAccount.address(), payload, extraArgs); - const bcsTxn = AptosClient.generateBCSTransaction(forAccount, rawTransaction); - return this.submitSignedBCSTransaction(bcsTxn); - } - - /** - * Lookup the original address by the current derived address - * @param addressOrAuthKey - * @returns original address - */ - async lookupOriginalAddress(addressOrAuthKey: MaybeHexString): Promise { - const resource = await this.getAccountResource("0x1", "0x1::account::OriginatingAddress"); - - const { - address_map: { handle }, - } = resource.data as any; - - const origAddress = await this.getTableItem(handle, { - key_type: "address", - value_type: "address", - key: HexString.ensure(addressOrAuthKey).hex(), - }); - - return new HexString(origAddress); - } - - /** - * Get block by height - * - * @param blockHeight Block height to lookup. Starts at 0 - * @param withTransactions If set to true, include all transactions in the block - * - * @returns Block - */ - @parseApiError - async getBlockByHeight(blockHeight: number, withTransactions?: boolean): Promise { - return this.client.blocks.getBlockByHeight(blockHeight, withTransactions); - } - - /** - * Get block by block transaction version - * - * @param version Ledger version to lookup block information for - * @param withTransactions If set to true, include all transactions in the block - * - * @returns Block - */ - @parseApiError - async getBlockByVersion(version: number, withTransactions?: boolean): Promise { - return this.client.blocks.getBlockByVersion(version, withTransactions); - } - - /** - * Call for a move view function - * - * @param payload Transaction payload - * @param version (optional) Ledger version to lookup block information for - * - * @returns MoveValue[] - */ - @parseApiError - async view(payload: Gen.ViewRequest, ledger_version?: string): Promise { - return this.client.view.view(payload, ledger_version); - } - - // eslint-disable-next-line class-methods-use-this - clearCache(tags: string[]) { - clear(tags); - } -} - -export class ApiError extends Error { - constructor( - public readonly status: number, - public readonly message: string, - public readonly errorCode?: string, - public readonly vmErrorCode?: string, - ) { - super(message); - } -} - -/** - * This error is used by `waitForTransactionWithResult` when waiting for a - * transaction times out. - */ -export class WaitForTransactionError extends Error { - public readonly lastSubmittedTransaction: Gen.Transaction | undefined; - - constructor(message: string, lastSubmittedTransaction: Gen.Transaction | undefined) { - super(message); - this.lastSubmittedTransaction = lastSubmittedTransaction; - } -} - -/** - * This error is used by `waitForTransactionWithResult` if `checkSuccess` is true. - * See that function for more information. - */ -export class FailedTransactionError extends Error { - public readonly transaction: Gen.Transaction; - - constructor(message: string, transaction: Gen.Transaction) { - super(message); - this.transaction = transaction; - } -} - -/** - * Creates a decorator to parse Gen.ApiError and return a wrapped error that is more developer friendly - */ -function parseApiError(target: unknown, propertyKey: string, descriptor: PropertyDescriptor) { - const childFunction = descriptor.value; - // eslint-disable-next-line no-param-reassign - descriptor.value = async function wrapper(...args: any[]) { - try { - // We need to explicitly await here so that the function is called and - // potentially throws an error. If we just return without awaiting, the - // promise is returned directly and the catch block cannot trigger. - const res = await childFunction.apply(this, [...args]); - return res; - } catch (e) { - if (e instanceof Gen.ApiError) { - throw new ApiError( - e.status, - JSON.stringify({ message: e.message, ...e.body }), - e.body?.error_code, - e.body?.vm_error_code, - ); - } - throw e; - } - }; - return descriptor; -} diff --git a/m1/JavaScript-client/src/providers/index.ts b/m1/JavaScript-client/src/providers/index.ts deleted file mode 100644 index a6528d3ca..000000000 --- a/m1/JavaScript-client/src/providers/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./indexer"; -export * from "./aptos_client"; -export * from "./provider"; diff --git a/m1/JavaScript-client/src/providers/indexer.ts b/m1/JavaScript-client/src/providers/indexer.ts deleted file mode 100644 index 1aed15808..000000000 --- a/m1/JavaScript-client/src/providers/indexer.ts +++ /dev/null @@ -1,313 +0,0 @@ -import axios from "axios"; - -import { AnyNumber } from "../bcs/types"; -import { HexString, MaybeHexString } from "../utils"; -import { - GetAccountTokensCountQuery, - GetAccountCoinsDataQuery, - GetAccountCurrentTokensQuery, - GetAccountTransactionsCountQuery, - GetAccountTransactionsDataQuery, - GetCurrentDelegatorBalancesCountQuery, - GetDelegatedStakingActivitiesQuery, - GetIndexerLedgerInfoQuery, - GetTokenActivitiesCountQuery, - GetTokenActivitiesQuery, - GetTokenDataQuery, - GetTokenOwnersDataQuery, - GetTopUserTransactionsQuery, - GetUserTransactionsQuery, -} from "../indexer/generated/operations"; -import { - GetAccountTokensCount, - GetAccountCoinsData, - GetAccountCurrentTokens, - GetAccountTransactionsCount, - GetAccountTransactionsData, - GetCurrentDelegatorBalancesCount, - GetDelegatedStakingActivities, - GetIndexerLedgerInfo, - GetTokenActivities, - GetTokenActivitiesCount, - GetTokenData, - GetTokenOwnersData, - GetTopUserTransactions, - GetUserTransactions, -} from "../indexer/generated/queries"; - -/** - * Controls the number of results that are returned and the starting position of those results. - * limit specifies the maximum number of items or records to return in a query result. - * offset parameter specifies the starting position of the query result within the set of data. - * For example, if you want to retrieve records 11-20, - * you would set the offset parameter to 10 (i.e., the index of the first record to retrieve is 10) - * and the limit parameter to 10 (i.e., the number of records to retrieve is 10)) - */ -interface PaginationArgs { - offset?: AnyNumber; - limit?: number; -} - -type GraphqlQuery = { - query: string; - variables?: {}; -}; -/** - * Provides methods for retrieving data from Aptos Indexer. - * For more detailed Queries specification see - * {@link https://cloud.hasura.io/public/graphiql?endpoint=https://indexer.mainnet.aptoslabs.com/v1/graphql} - */ -export class IndexerClient { - endpoint: string; - - /** - * @param endpoint URL of the Aptos Indexer API endpoint. - */ - constructor(endpoint: string) { - this.endpoint = endpoint; - } - - /** - * Indexer only accepts address in the long format, i.e a 66 chars long -> 0x<64 chars> - * This method makes sure address is 66 chars long. - * @param address - */ - static validateAddress(address: string): void { - if (address.length < 66) { - throw new Error("Address needs to be 66 chars long."); - } - } - - /** - * Builds a axios client call to fetch data from Aptos Indexer. - * - * @param graphqlQuery A GraphQL query to pass in the `data` axios call. - */ - async queryIndexer(graphqlQuery: GraphqlQuery): Promise { - const { data } = await axios.post(this.endpoint, graphqlQuery); - if (data.errors) { - throw new Error(`Indexer data error ${JSON.stringify(data.errors, null, " ")}`); - } - return data.data; - } - - /** - * Queries Indexer Ledger Info - * - * @returns GetLedgerInfoQuery response type - */ - async getIndexerLedgerInfo(): Promise { - const graphqlQuery = { - query: GetIndexerLedgerInfo, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries an Aptos account's NFTs by owner address - * - * @param ownerAddress Hex-encoded 32 byte Aptos account address - * @returns GetAccountCurrentTokensQuery response type - */ - async getAccountNFTs(ownerAddress: MaybeHexString, options?: PaginationArgs): Promise { - const address = HexString.ensure(ownerAddress).hex(); - IndexerClient.validateAddress(address); - const graphqlQuery = { - query: GetAccountCurrentTokens, - variables: { address, offset: options?.offset, limit: options?.limit }, - }; - - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries a token activities by token id hash - * - * @param idHash token id hash - * @returns GetTokenActivitiesQuery response type - */ - async getTokenActivities(idHash: string, options?: PaginationArgs): Promise { - const graphqlQuery = { - query: GetTokenActivities, - variables: { idHash, offset: options?.offset, limit: options?.limit }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries an account coin data - * - * @param ownerAddress Owner address - * @returns GetAccountCoinsDataQuery response type - */ - async getAccountCoinsData(ownerAddress: MaybeHexString, options?: PaginationArgs): Promise { - const address = HexString.ensure(ownerAddress).hex(); - IndexerClient.validateAddress(address); - const graphqlQuery = { - query: GetAccountCoinsData, - variables: { owner_address: address, offset: options?.offset, limit: options?.limit }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Gets the count of tokens owned by an account - * - * @param ownerAddress Owner address - * @returns AccountTokensCountQuery response type - */ - async getAccountTokensCount(ownerAddress: MaybeHexString): Promise { - const address = HexString.ensure(ownerAddress).hex(); - IndexerClient.validateAddress(address); - const graphqlQuery = { - query: GetAccountTokensCount, - variables: { owner_address: address }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Gets the count of transactions submitted by an account - * - * @param address Account address - * @returns GetAccountTransactionsCountQuery response type - */ - async getAccountTransactionsCount(accountAddress: MaybeHexString): Promise { - const address = HexString.ensure(accountAddress).hex(); - IndexerClient.validateAddress(address); - const graphqlQuery = { - query: GetAccountTransactionsCount, - variables: { address }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries an account transactions data - * - * @param address Account address - * @returns GetAccountTransactionsDataQuery response type - */ - async getAccountTransactionsData( - accountAddress: MaybeHexString, - options?: PaginationArgs, - ): Promise { - const address = HexString.ensure(accountAddress).hex(); - IndexerClient.validateAddress(address); - const graphqlQuery = { - query: GetAccountTransactionsData, - variables: { address, offset: options?.offset, limit: options?.limit }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries delegated staking activities - * - * @param delegatorAddress Delegator address - * @param poolAddress Pool address - * @returns GetDelegatedStakingActivitiesQuery response type - */ - async getDelegatedStakingActivities( - delegatorAddress: MaybeHexString, - poolAddress: MaybeHexString, - ): Promise { - const delegator = HexString.ensure(delegatorAddress).hex(); - const pool = HexString.ensure(poolAddress).hex(); - IndexerClient.validateAddress(delegator); - IndexerClient.validateAddress(pool); - const graphqlQuery = { - query: GetDelegatedStakingActivities, - variables: { - delegatorAddress: delegator, - poolAddress: pool, - }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Gets the count of token's activities - * - * @param tokenId Token ID - * @returns GetTokenActivitiesCountQuery response type - */ - async getTokenActivitiesCount(tokenId: string): Promise { - const graphqlQuery = { - query: GetTokenActivitiesCount, - variables: { token_id: tokenId }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries token data - * - * @param tokenId Token ID - * @returns GetTokenDataQuery response type - */ - async getTokenData(tokenId: string): Promise { - const graphqlQuery = { - query: GetTokenData, - variables: { token_id: tokenId }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries token owners data - * - * @param tokenId Token ID - * @param propertyVersion Property version - * @returns GetTokenOwnersDataQuery response type - */ - async getTokenOwnersData(tokenId: string, propertyVersion: number): Promise { - const graphqlQuery = { - query: GetTokenOwnersData, - variables: { token_id: tokenId, property_version: propertyVersion }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries top user transactions - * - * @param limit - * @returns GetTopUserTransactionsQuery response type - */ - async getTopUserTransactions(limit: number): Promise { - const graphqlQuery = { - query: GetTopUserTransactions, - variables: { limit }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries top user transactions - * - * @returns GetUserTransactionsQuery response type - */ - async getUserTransactions(startVersion?: number, options?: PaginationArgs): Promise { - const graphqlQuery = { - query: GetUserTransactions, - variables: { start_version: startVersion, offset: options?.offset, limit: options?.limit }, - }; - return this.queryIndexer(graphqlQuery); - } - - /** - * Queries current delegator balances count - * - * @returns GetCurrentDelegatorBalancesCountQuery response type - */ - async getCurrentDelegatorBalancesCount(poolAddress: MaybeHexString): Promise { - const address = HexString.ensure(poolAddress).hex(); - IndexerClient.validateAddress(address); - const graphqlQuery = { - query: GetCurrentDelegatorBalancesCount, - variables: { poolAddress: address }, - }; - return this.queryIndexer(graphqlQuery); - } -} diff --git a/m1/JavaScript-client/src/providers/provider.ts b/m1/JavaScript-client/src/providers/provider.ts deleted file mode 100644 index 23de25271..000000000 --- a/m1/JavaScript-client/src/providers/provider.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { AptosClient } from "./aptos_client"; -import { IndexerClient } from "./indexer"; - -import * as Gen from "../generated/index"; -import { CustomEndpoints, Network, NetworkToIndexerAPI, NetworkToNodeAPI } from "../utils"; - -type NetworkWithCustom = Network | "CUSTOM"; -/** - * Builds a Provider class with an aptos client configured to connect to an Aptos node - * and indexer client configured to connect to Aptos Indexer. - * - * It creates AptosClient and IndexerClient instances based on the network or custom endpoints provided. - * - * This class holds both AptosClient and IndexerClient classes's methods and properties so we - * can instantiate the Provider class and use it to query full node and/or Indexer. - * - * @example An example of how to use this class - * ``` - * const provider = new Provider(Network.DEVNET) - * const account = await provider.getAccount("0x123"); - * const accountNFTs = await provider.getAccountNFTs("0x123"); - * ``` - * - * @param network enum of type Network - MAINNET | TESTNET | DEVENET or custom endpoints of type CustomEndpoints - * @param config AptosClient config arg - additional configuration options for the generated Axios client. - */ -export class Provider { - aptosClient: AptosClient; - - indexerClient: IndexerClient; - - network: NetworkWithCustom; - - constructor( - network: Network | CustomEndpoints, - config?: Partial, - doNotFixNodeUrl: boolean = false, - ) { - let fullNodeUrl = null; - let indexerUrl = null; - - if (typeof network === "object" && isCustomEndpoints(network)) { - fullNodeUrl = network.fullnodeUrl; - indexerUrl = network.indexerUrl; - this.network = "CUSTOM"; - } else { - fullNodeUrl = NetworkToNodeAPI[network]; - indexerUrl = NetworkToIndexerAPI[network]; - this.network = network; - } - - if (!fullNodeUrl || !indexerUrl) { - throw new Error("network is not provided"); - } - - this.aptosClient = new AptosClient(fullNodeUrl, config, doNotFixNodeUrl); - this.indexerClient = new IndexerClient(indexerUrl); - } -} - -export interface Provider extends AptosClient, IndexerClient {} - -/** -In TypeScript, we can’t inherit or extend from more than one class, -Mixins helps us to get around that by creating a partial classes -that we can combine to form a single class that contains all the methods and properties from the partial classes. -{@link https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern} - -Here, we combine AptosClient and IndexerClient classes into one Provider class that holds all -methods and properties from both classes. -*/ -function applyMixin(targetClass: any, baseClass: any, baseClassProp: string) { - Object.getOwnPropertyNames(baseClass.prototype).forEach((propertyName) => { - const propertyDescriptor = Object.getOwnPropertyDescriptor(baseClass.prototype, propertyName); - if (!propertyDescriptor) return; - // eslint-disable-next-line func-names - propertyDescriptor.value = function (...args: any) { - return (this as any)[baseClassProp][propertyName](...args); - }; - Object.defineProperty(targetClass.prototype, propertyName, propertyDescriptor); - }); -} - -applyMixin(Provider, AptosClient, "aptosClient"); -applyMixin(Provider, IndexerClient, "indexerClient"); - -// use exhaustive type predicates -function isCustomEndpoints(network: CustomEndpoints): network is CustomEndpoints { - return ( - network.fullnodeUrl !== undefined && - typeof network.fullnodeUrl === "string" && - network.indexerUrl !== undefined && - typeof network.indexerUrl === "string" - ); -} diff --git a/m1/JavaScript-client/src/tests/e2e/ans_client.test.ts b/m1/JavaScript-client/src/tests/e2e/ans_client.test.ts deleted file mode 100644 index 641058e51..000000000 --- a/m1/JavaScript-client/src/tests/e2e/ans_client.test.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { AptosAccount } from "../../account"; -import { AnsClient } from "../../plugins/ans_client"; -import { Provider } from "../../providers"; -import { HexString, Network } from "../../utils"; -import { ANS_OWNER_ADDRESS, ANS_OWNER_PK, getFaucetClient, longTestTimeout, NODE_URL } from "../unit/test_helper.test"; - -const alice = new AptosAccount(); -const ACCOUNT_ADDRESS = alice.address().hex(); -// generate random name so we can run the test against local tesnet without the need to re-run it each time. -// This will produce a string anywhere between zero and 12 characters long, usually 11 characters, only lower-case and numbers -const DOMAIN_NAME = Math.random().toString(36).slice(2); - -describe("ANS", () => { - beforeAll(async () => { - const faucetClient = getFaucetClient(); - await faucetClient.fundAccount(alice.address(), 100_000_000_000); - }, longTestTimeout); - - test("fails to create a new ANS class instance", () => { - const provider = new Provider({ fullnodeUrl: "full-node-url", indexerUrl: "indexer-url" }); - expect(() => new AnsClient(provider)).toThrow("Error: For custom providers, you must pass in a contract address"); - }); - - test("creates a new ANS class instance", () => { - const provider = new Provider({ fullnodeUrl: "full-node-url", indexerUrl: "indexer-url" }); - const ans_client = new AnsClient(provider, ANS_OWNER_ADDRESS); - expect(ans_client).toHaveProperty("contractAddress"); - }); - - test("sets the contract address to be the provided one", () => { - const provider = new Provider({ fullnodeUrl: "full-node-url", indexerUrl: "indexer-url" }); - const ans_client = new AnsClient(provider, ANS_OWNER_ADDRESS); - expect(ans_client.contractAddress).toEqual(ANS_OWNER_ADDRESS); - }); - - test("sets the contract address to be the one that matches the provided node url", () => { - const provider = new Provider(Network.TESTNET); - const ans_client = new AnsClient(provider, ANS_OWNER_ADDRESS); - expect(ans_client.contractAddress).toEqual("0x5f8fd2347449685cf41d4db97926ec3a096eaf381332be4f1318ad4d16a8497c"); - }); - - test( - "init reverse lookup registry for contract admin", - async () => { - const owner = new AptosAccount(new HexString(ANS_OWNER_PK).toUint8Array()); - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans_client = new AnsClient(provider, ANS_OWNER_ADDRESS); - const txnHash = await ans_client.initReverseLookupRegistry(owner); - await provider.waitForTransactionWithResult(txnHash, { checkSuccess: true }); - }, - longTestTimeout, - ); - - test( - "mint name", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const txnHash = await ans.mintAptosName(alice, DOMAIN_NAME); - await provider.waitForTransactionWithResult(txnHash, { checkSuccess: true }); - }, - longTestTimeout, - ); - - test( - "get name by address", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const name = await ans.getPrimaryNameByAddress(ACCOUNT_ADDRESS); - expect(name).toEqual(DOMAIN_NAME); - }, - longTestTimeout, - ); - - test( - "get address by name", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const address = await ans.getAddressByName(DOMAIN_NAME); - expect(address).toEqual(ACCOUNT_ADDRESS); - }, - longTestTimeout, - ); - - test( - "get address by name with .apt", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const address = await ans.getAddressByName(`${DOMAIN_NAME}.apt`); - expect(address).toEqual(ACCOUNT_ADDRESS); - }, - longTestTimeout, - ); - - test( - "get address by subdomain_name", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const address = await ans.getAddressByName(`sub.${DOMAIN_NAME}`); - expect(address).toBeNull; - }, - longTestTimeout, - ); - - test( - "get address by subdomain_name with .apt", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const address = await ans.getAddressByName(`sub.${DOMAIN_NAME}.apt`); - expect(address).toBeNull; - }, - longTestTimeout, - ); - - test( - "returns null for an invalid domain", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const address = await ans.getAddressByName(`${DOMAIN_NAME}-`); - expect(address).toBeNull; - }, - longTestTimeout, - ); - - test( - "returns null for an invalid subdomain", - async () => { - const provider = new Provider({ fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }); - const ans = new AnsClient(provider, ANS_OWNER_ADDRESS); - - const address = await ans.getAddressByName(`sub.${DOMAIN_NAME}.apt-`); - expect(address).toBeNull; - }, - longTestTimeout, - ); -}); diff --git a/m1/JavaScript-client/src/tests/e2e/aptos_client.test.ts b/m1/JavaScript-client/src/tests/e2e/aptos_client.test.ts deleted file mode 100644 index de0a6e21c..000000000 --- a/m1/JavaScript-client/src/tests/e2e/aptos_client.test.ts +++ /dev/null @@ -1,658 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AptosClient } from "../../providers/aptos_client"; -import * as Gen from "../../generated/index"; -import { AptosAccount } from "../../account/aptos_account"; -import { - TxnBuilderTypes, - TransactionBuilderMultiEd25519, - TransactionBuilderRemoteABI, -} from "../../transaction_builder"; -import { AptosToken, TokenClient } from "../../plugins"; -import { HexString } from "../../utils"; -import { getFaucetClient, longTestTimeout, NODE_URL, PROVIDER_LOCAL_NETWORK_CONFIG } from "../unit/test_helper.test"; -import { bcsSerializeUint64, bcsToBytes } from "../../bcs"; -import { AccountAddress, Ed25519PublicKey, stringStructTag, TypeTagStruct } from "../../aptos_types"; -import { Provider } from "../../providers"; -import { BCS } from "../.."; - -const account = "0x1::account::Account"; - -const aptosCoin = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"; - -const coinTransferFunction = "0x1::coin::transfer"; - -test("node url empty", () => { - expect(() => { - const client = new AptosClient(""); - client.getAccount("0x1"); - }).toThrow("Node URL cannot be empty."); -}); - -test("gets genesis account", async () => { - const client = new AptosClient(NODE_URL); - const genesisAccount = await client.getAccount("0x1"); - expect(genesisAccount.authentication_key.length).toBe(66); - expect(genesisAccount.sequence_number).not.toBeNull(); -}); - -test("gets transactions", async () => { - const client = new AptosClient(NODE_URL); - const transactions = await client.getTransactions(); - expect(transactions.length).toBeGreaterThan(0); -}); - -test("gets genesis resources", async () => { - const client = new AptosClient(NODE_URL); - const resources = await client.getAccountResources("0x1"); - const accountResource = resources.find((r) => r.type === account); - expect(accountResource).toBeDefined(); -}); - -test("gets the Account resource", async () => { - const client = new AptosClient(NODE_URL); - const accountResource = await client.getAccountResource("0x1", account); - expect(accountResource).toBeDefined(); -}); - -test("gets ledger info", async () => { - const client = new AptosClient(NODE_URL); - const ledgerInfo = await client.getLedgerInfo(); - expect(ledgerInfo.chain_id).toBeGreaterThan(1); - expect(parseInt(ledgerInfo.ledger_version, 10)).toBeGreaterThan(0); -}); - -test("gets account modules", async () => { - const client = new AptosClient(NODE_URL); - const modules = await client.getAccountModules("0x1"); - const module = modules.find((r) => r.abi!.name === "aptos_coin"); - expect(module!.abi!.address).toBe("0x1"); -}); - -test("gets the AptosCoin module", async () => { - const client = new AptosClient(NODE_URL); - const module = await client.getAccountModule("0x1", "aptos_coin"); - expect(module!.abi!.address).toBe("0x1"); -}); - -test( - "submits bcs transaction", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const account1 = new AptosAccount(); - await faucetClient.fundAccount(account1.address(), 100_000_000); - let resources = await client.getAccountResources(account1.address()); - let accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("100000000"); - - const account2 = new AptosAccount(); - await faucetClient.fundAccount(account2.address(), 0); - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("0"); - - const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin")); - - const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction( - TxnBuilderTypes.EntryFunction.natural( - "0x1::coin", - "transfer", - [token], - [bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(account2.address())), bcsSerializeUint64(717)], - ), - ); - - const rawTxn = await client.generateRawTransaction(account1.address(), entryFunctionPayload); - - const bcsTxn = AptosClient.generateBCSTransaction(account1, rawTxn); - const transactionRes = await client.submitSignedBCSTransaction(bcsTxn); - - await client.waitForTransaction(transactionRes.hash); - - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("717"); - }, - longTestTimeout, -); - -test( - "submits generic type bcs transaction", - async () => { - const provider = new Provider(PROVIDER_LOCAL_NETWORK_CONFIG); - const aptosToken = new AptosToken(provider); - const account1 = new AptosAccount(); - const faucetClient = getFaucetClient(); - - await faucetClient.fundAccount(account1.address(), 100_000_000); - let resources = await provider.getAccountResources(account1.address()); - let accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("100000000"); - - let tokenAddress = ""; - - await provider.waitForTransaction( - await aptosToken.createCollection(account1, "Collection description", "Collection Name", "https://aptos.dev", 5, { - royaltyNumerator: 10, - royaltyDenominator: 10, - }), - ); - const txn = await provider.waitForTransactionWithResult( - await aptosToken.mint( - account1, - "Collection Name", - "Token Description", - "Token Name", - "https://aptos.dev/img/nyan.jpeg", - ["key"], - ["bool"], - ["true"], - ), - { checkSuccess: true }, - ); - tokenAddress = (txn as Gen.UserTransaction).events[0].data.token; - console.log(tokenAddress); - - const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x4::token::Token")); - const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction( - TxnBuilderTypes.EntryFunction.natural( - "0x4::aptos_token", - "add_typed_property", - [token, new TypeTagStruct(stringStructTag)], - [ - BCS.bcsToBytes(AccountAddress.fromHex(tokenAddress)), - BCS.bcsSerializeStr("bcsKey"), - BCS.bcsSerializeStr("bcs value"), - ], - ), - ); - const rawTxn = await provider.generateRawTransaction(account1.address(), entryFunctionPayload); - const bcsTxn = AptosClient.generateBCSTransaction(account1, rawTxn); - const transactionRes = await provider.submitSignedBCSTransaction(bcsTxn); - await provider.waitForTransaction(transactionRes.hash, { checkSuccess: true }); - }, - longTestTimeout, -); - -test( - "submits transaction with remote ABI", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const account1 = new AptosAccount(); - await faucetClient.fundAccount(account1.address(), 100_000_000); - let resources = await client.getAccountResources(account1.address()); - let accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("100000000"); - - const account2 = new AptosAccount(); - await faucetClient.fundAccount(account2.address(), 0); - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("0"); - - const builder = new TransactionBuilderRemoteABI(client, { sender: account1.address() }); - const rawTxn = await builder.build( - "0x1::coin::transfer", - ["0x1::aptos_coin::AptosCoin"], - [account2.address(), 400], - ); - - const bcsTxn = AptosClient.generateBCSTransaction(account1, rawTxn); - const transactionRes = await client.submitSignedBCSTransaction(bcsTxn); - - await client.waitForTransaction(transactionRes.hash); - - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("400"); - }, - longTestTimeout, -); - -test( - "submits multisig transaction simulation", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const account1 = new AptosAccount(); - const account2 = new AptosAccount(); - const account3 = new AptosAccount(); - const multiSigPublicKey = new TxnBuilderTypes.MultiEd25519PublicKey( - [ - new TxnBuilderTypes.Ed25519PublicKey(account1.signingKey.publicKey), - new TxnBuilderTypes.Ed25519PublicKey(account2.signingKey.publicKey), - new TxnBuilderTypes.Ed25519PublicKey(account3.signingKey.publicKey), - ], - 2, - ); - - const authKey = TxnBuilderTypes.AuthenticationKey.fromMultiEd25519PublicKey(multiSigPublicKey); - - const mutisigAccountAddress = authKey.derivedAddress(); - await faucetClient.fundAccount(mutisigAccountAddress, 50000000); - - let resources = await client.getAccountResources(mutisigAccountAddress); - let accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("50000000"); - - const account4 = new AptosAccount(); - await faucetClient.fundAccount(account4.address(), 0); - resources = await client.getAccountResources(account4.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("0"); - - const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin")); - - const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction( - TxnBuilderTypes.EntryFunction.natural( - "0x1::coin", - "transfer", - [token], - [bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(account4.address())), bcsSerializeUint64(123)], - ), - ); - - const rawTxn = await client.generateRawTransaction(mutisigAccountAddress, entryFunctionPayload); - - const txnBuilder = new TransactionBuilderMultiEd25519((signingMessage: TxnBuilderTypes.SigningMessage) => { - const sigHexStr1 = account1.signBuffer(signingMessage); - const sigHexStr3 = account3.signBuffer(signingMessage); - const bitmap = TxnBuilderTypes.MultiEd25519Signature.createBitmap([0, 2]); - - const muliEd25519Sig = new TxnBuilderTypes.MultiEd25519Signature( - [ - new TxnBuilderTypes.Ed25519Signature(sigHexStr1.toUint8Array()), - new TxnBuilderTypes.Ed25519Signature(sigHexStr3.toUint8Array()), - ], - bitmap, - ); - - return muliEd25519Sig; - }, multiSigPublicKey); - - // simulate transaction - const [simulateTransactionRes] = await client.simulateTransaction(multiSigPublicKey, rawTxn, { - estimateGasUnitPrice: true, - estimateMaxGasAmount: true, - estimatePrioritizedGasUnitPrice: true, - }); - - expect(parseInt(simulateTransactionRes.gas_used, 10) > 0); - expect(simulateTransactionRes.success); - - const bcsTxn = txnBuilder.sign(rawTxn); - const transactionRes = await client.submitSignedBCSTransaction(bcsTxn); - - await client.waitForTransaction(transactionRes.hash); - - resources = await client.getAccountResources(account4.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as any).coin.value).toBe("123"); - }, - longTestTimeout, -); - -test( - "submits json transaction simulation", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const account1 = new AptosAccount(); - const account2 = new AptosAccount(); - const txns1 = await faucetClient.fundAccount(account1.address(), 1000000); - const txns2 = await faucetClient.fundAccount(account2.address(), 1000000); - const tx1 = await client.getTransactionByHash(txns1[0]); - const tx2 = await client.getTransactionByHash(txns2[0]); - expect(tx1.type).toBe("user_transaction"); - expect(tx2.type).toBe("user_transaction"); - const checkAptosCoin = async () => { - const resources1 = await client.getAccountResources(account1.address()); - const resources2 = await client.getAccountResources(account2.address()); - const account1Resource = resources1.find((r) => r.type === aptosCoin); - const account2Resource = resources2.find((r) => r.type === aptosCoin); - expect((account1Resource!.data as { coin: { value: string } }).coin.value).toBe("1000000"); - expect((account2Resource!.data as { coin: { value: string } }).coin.value).toBe("1000000"); - }; - await checkAptosCoin(); - - const payload: Gen.TransactionPayload = { - type: "entry_function_payload", - function: coinTransferFunction, - type_arguments: ["0x1::aptos_coin::AptosCoin"], - arguments: [account2.address().hex(), 100000], - }; - const txnRequest = await client.generateTransaction(account1.address(), payload); - [account1, new Ed25519PublicKey(account1.pubKey().toUint8Array())].forEach(async (accountOrAddress) => { - const transactionRes = ( - await client.simulateTransaction(accountOrAddress, txnRequest, { - estimateGasUnitPrice: true, - estimateMaxGasAmount: true, - estimatePrioritizedGasUnitPrice: true, - }) - )[0]; - expect(parseInt(transactionRes.gas_used, 10) > 0); - expect(transactionRes.success); - const account2AptosCoin = transactionRes.changes.filter((change) => { - if (change.type !== "write_resource") { - return false; - } - const write = change as Gen.WriteResource; - - return ( - write.address === account2.address().hex() && - write.data.type === aptosCoin && - (write.data.data as { coin: { value: string } }).coin.value === "1100000" - ); - }); - expect(account2AptosCoin).toHaveLength(1); - }); - await checkAptosCoin(); - }, - longTestTimeout, -); - -test( - "submits bcs transaction simulation", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const account1 = new AptosAccount(); - const account2 = new AptosAccount(); - const txns1 = await faucetClient.fundAccount(account1.address(), 100_000_000); - const txns2 = await faucetClient.fundAccount(account2.address(), 100_000_000); - const tx1 = await client.getTransactionByHash(txns1[0]); - const tx2 = await client.getTransactionByHash(txns2[0]); - expect(tx1.type).toBe("user_transaction"); - expect(tx2.type).toBe("user_transaction"); - const checkAptosCoin = async () => { - const resources1 = await client.getAccountResources(account1.address()); - const resources2 = await client.getAccountResources(account2.address()); - const account1Resource = resources1.find((r) => r.type === aptosCoin); - const account2Resource = resources2.find((r) => r.type === aptosCoin); - expect((account1Resource!.data as { coin: { value: string } }).coin.value).toBe("100000000"); - expect((account2Resource!.data as { coin: { value: string } }).coin.value).toBe("100000000"); - }; - await checkAptosCoin(); - - const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin")); - const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction( - TxnBuilderTypes.EntryFunction.natural( - "0x1::coin", - "transfer", - [token], - [bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(account2.address())), bcsSerializeUint64(1000)], - ), - ); - - const rawTxn = await client.generateRawTransaction(account1.address(), entryFunctionPayload); - - const bcsTxn = AptosClient.generateBCSSimulation(account1, rawTxn); - const transactionRes = (await client.submitBCSSimulation(bcsTxn))[0]; - expect(parseInt(transactionRes.gas_used, 10) > 0); - expect(transactionRes.success); - const account2AptosCoin = transactionRes.changes.filter((change) => { - if (change.type !== "write_resource") { - return false; - } - const write = change as Gen.WriteResource; - - return ( - write.address === account2.address().toShortString() && - write.data.type === aptosCoin && - (write.data.data as { coin: { value: string } }).coin.value === "100001000" - ); - }); - expect(account2AptosCoin).toHaveLength(1); - await checkAptosCoin(); - }, - longTestTimeout, -); - -test( - "submits multiagent transaction", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - const tokenClient = new TokenClient(client); - - const alice = new AptosAccount(); - const bob = new AptosAccount(); - - // Fund both Alice's and Bob's Account - await faucetClient.fundAccount(alice.address(), 100000000); - await faucetClient.fundAccount(bob.address(), 100000000); - - const collectionName = "AliceCollection"; - const tokenName = "Alice Token"; - - async function ensureTxnSuccess(txnHashPromise: Promise) { - const txnHash = await txnHashPromise; - const txn = await client.waitForTransactionWithResult(txnHash); - expect((txn as any)?.success).toBe(true); - } - - // Create collection and token on Alice's account - await ensureTxnSuccess( - tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"), - ); - - await ensureTxnSuccess( - tokenClient.createToken( - alice, - collectionName, - tokenName, - "Alice's simple token", - 1, - "https://aptos.dev/img/nyan.jpeg", - 1000, - alice.address(), - 0, - 0, - ["key"], - ["2"], - ["u64"], - ), - ); - - const propertyVersion = 0; - const tokenId = { - token_data_id: { - creator: alice.address().hex(), - collection: collectionName, - name: tokenName, - }, - property_version: `${propertyVersion}`, - }; - - // Transfer Token from Alice's Account to Bob's Account - await tokenClient.getCollectionData(alice.address().hex(), collectionName); - let aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId); - expect(aliceBalance.amount).toBe("1"); - - const txnHash = await tokenClient.directTransferToken( - alice, - bob, - alice.address(), - collectionName, - tokenName, - 1, - propertyVersion, - ); - - await client.waitForTransaction(txnHash, { checkSuccess: true }); - - aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId); - expect(aliceBalance.amount).toBe("0"); - - const bobBalance = await tokenClient.getTokenForAccount(bob.address().hex(), tokenId); - expect(bobBalance.amount).toBe("1"); - }, - longTestTimeout, -); - -test( - "publishes a package", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const account1 = new AptosAccount( - new HexString("0x883fdd67576e5fdceb370ba665b8af8856d0cae63fd808b8d16077c6b008ea8c").toUint8Array(), - ); - await faucetClient.fundAccount(account1.address(), 100_000_000); - - const txnHash = await client.publishPackage( - account1, - new HexString( - // eslint-disable-next-line max-len - "084578616d706c657301000000000000000040314137344146383742383132393043323533323938383036373846304137444637393737373637383734334431434345443230413446354345334238464446388f011f8b08000000000002ff3dccc10ac2300c06e07b9ea2f46ee70b78f0a02f31c6886d74a55d5b1a51417c7713c1915c927cf9c7863ee18d2628b89239187b7ae1da32b18507758eb5e872efa42cc088217462269e60a19ceb7cc9d527bf60fcb9594da0462550f151d9b1dd2b9fbba43f6b4f82de465e302b776e90befe8f03aadd6db3351ff802f2294cdfa100000001076d6573736167658f051f8b08000000000002ff95555d6bdb30147dcfafb8ed20d8c52c1d8c3194a6ec83b0be747be8dec6108a7d9d983a5226c94dc3f07f9f2cd98e6cc769e787884857e79e73bfb4154991236c30cf055de5227e8c372ce3846c5129b646f83b01f3150a41e984109452c879774f656b8e834d2d33be3e6eb29d168aa6926d712fe423212c8e45c175dfc27979c2ea64329b910b722b518942c6682d0d6e116bb877f4ee449ea0840d53f088879a6cf5d5f409381e843cd835ea1b5023979bc57a5404ec4ac8b25aee184f72bca95d7db586f6e0d6c19486df8d21d8f23b41d0bb65592652ec226323247a6c5329b6f445ca5a9cb7291d81d96c063f37681c640ab86894c2cef03434ac4d2cb8d2b0fcfe83de2f1f1e3e7f5b12283ebc87055ccf1dc8ae58e5590c69c1618dbaf11bb0249104aa5fb311f669008bff149939eaa5e728942985525f04f89c29ad6e3a66b7163d8cc0d618215c689a9a1249028f6718ce5bb0abe94a18d33d5de762c5f293686f6be67e806a6d2616f260152a5fa12b4b23cd5675345649a1857a51708e1a6a485a11322176c0a6015c14a94883696de289cb52082e46c2e4e185a1e7ccd6b57842aa450b198d52eb75423476d06f91264284e3de6dd2cd68a71ca575f1cbb0fd5b02e60a7bc4aab819c24d5ae8c6b15f4027e5745be8b3d1990f40fd56337057d3a197a666ba97ebc980db4c3bd5c1d47887f1ebddb845a726c230193ebd6146fc09108bdde174eeca9eec718a260003ada5df2a6f7e6954ba89a931ff74fdfc2efc3dd646dc60d398717aa6a3c25736cdff34cbd8e342482c9169a44d51a44252a7a85b1d27f846d0767ca1d38fc1eaf2ae7a2423f8d2be9297d5341acc362ff6fdd119c262f10a543f9ddeec6b776be2e5a49cfc0325c63f11c007000000000300000000000000000000000000000000000000000000000000000000000000010e4170746f734672616d65776f726b00000000000000000000000000000000000000000000000000000000000000010b4170746f735374646c696200000000000000000000000000000000000000000000000000000000000000010a4d6f76655374646c696200", - ).toUint8Array(), - [ - new TxnBuilderTypes.Module( - new HexString( - // eslint-disable-next-line max-len - "a11ceb0b050000000c01000c020c12031e20043e04054228076ad50108bf024006ff020a108903450ace03150ce3035f0dc20404000001010102010301040105000606000007080005080700030e040106010009000100000a020300020f0404000410060000011106080106031209030106040705070105010802020c08020001030305080207080101060c010800010b0301090002070b030109000900076d657373616765076163636f756e74056572726f72056576656e74067369676e657206737472696e67124d6573736167654368616e67654576656e740d4d657373616765486f6c64657206537472696e670b6765745f6d6573736167650b7365745f6d6573736167650c66726f6d5f6d6573736167650a746f5f6d657373616765156d6573736167655f6368616e67655f6576656e74730b4576656e7448616e646c65096e6f745f666f756e640a616464726573735f6f66106e65775f6576656e745f68616e646c650a656d69745f6576656e746766284c3984add58e00d20ba272a40d33d5b4ea33c08a904254e28fdff97b9f000000000000000000000000000000000000000000000000000000000000000103080000000000000000126170746f733a3a6d657461646174615f7630310100000000000000000b454e4f5f4d4553534147451b5468657265206973206e6f206d6573736167652070726573656e740002020b08020c08020102020008020d0b030108000001000101030b0a002901030607001102270b002b0110001402010104010105210e0011030c020a022901200308050f0e000b010e00380012012d0105200b022a010c040a041000140c030a040f010b030a01120038010b010b040f0015020100010100", - ).toUint8Array(), - ), - ], - ); - - await client.waitForTransaction(txnHash); - - const txn = await client.getTransactionByHash(txnHash); - expect((txn as any).success).toBeTruthy(); - }, - longTestTimeout, -); - -test( - "rotates auth key ed25519", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const alice = new AptosAccount(); - await faucetClient.fundAccount(alice.address(), 100_000_000); - - const helperAccount = new AptosAccount(); - - const pendingTxn = await client.rotateAuthKeyEd25519(alice, helperAccount.signingKey.secretKey); - - await client.waitForTransaction(pendingTxn.hash); - - const origAddressHex = await client.lookupOriginalAddress(helperAccount.address()); - // Sometimes the returned addresses do not have leading 0s. To be safe, converting hex addresses to AccountAddress - const origAddress = TxnBuilderTypes.AccountAddress.fromHex(origAddressHex); - const aliceAddress = TxnBuilderTypes.AccountAddress.fromHex(alice.address()); - - expect(HexString.fromUint8Array(bcsToBytes(origAddress)).hex()).toBe( - HexString.fromUint8Array(bcsToBytes(aliceAddress)).hex(), - ); - }, - longTestTimeout, -); - -test( - "gets block by height", - async () => { - const blockHeight = 100; - const client = new AptosClient(NODE_URL); - const block = await client.getBlockByHeight(blockHeight); - expect(block.block_height).toBe(blockHeight.toString()); - }, - longTestTimeout, -); - -test( - "gets block by version", - async () => { - const version = 100; - const client = new AptosClient(NODE_URL); - const block = await client.getBlockByVersion(version); - expect(parseInt(block.first_version, 10)).toBeLessThanOrEqual(version); - expect(parseInt(block.last_version, 10)).toBeGreaterThanOrEqual(version); - }, - longTestTimeout, -); - -test( - "estimates max gas amount", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const alice = new AptosAccount(); - await faucetClient.fundAccount(alice.address(), 10000000); - - const maxGasAmount = await client.estimateMaxGasAmount(alice.address()); - - expect(maxGasAmount).toBeGreaterThan(BigInt(0)); - }, - longTestTimeout, -); - -test( - "view function", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const alice = new AptosAccount(); - await faucetClient.fundAccount(alice.address(), 100_000_000); - - const payload: Gen.ViewRequest = { - function: "0x1::coin::balance", - type_arguments: ["0x1::aptos_coin::AptosCoin"], - arguments: [alice.address().hex()], - }; - - const balance = await client.view(payload); - - expect(balance[0]).toBe("100000000"); - }, - longTestTimeout, -); - -test( - "view function with a struct return type", - async () => { - // This test is just to show that the view function supports a struct return type. - // We test against get_collection_mutability_config although - // b/c at the time of writing this is the only view function on the move side - // that can easily test a struct return type. - - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - const tokenClient = new TokenClient(client); - - const alice = new AptosAccount(); - // Fund Alice's Account - await faucetClient.fundAccount(alice.address(), 100000000); - - const collectionName = "AliceCollection"; - - // Create collection on Alice's account - await client.waitForTransaction( - await tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"), - { checkSuccess: true }, - ); - - const payload: Gen.ViewRequest = { - function: "0x3::token::get_collection_mutability_config", - type_arguments: [], - arguments: [alice.address().hex(), collectionName], - }; - - const collection = await client.view(payload); - expect(collection[0]).toMatchObject({ description: false, maximum: false, uri: false }); - }, - longTestTimeout, -); diff --git a/m1/JavaScript-client/src/tests/e2e/aptos_token.test.ts b/m1/JavaScript-client/src/tests/e2e/aptos_token.test.ts deleted file mode 100644 index 525841a14..000000000 --- a/m1/JavaScript-client/src/tests/e2e/aptos_token.test.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { AptosAccount } from "../../account"; -import { UserTransaction } from "../../generated"; -import { AptosToken } from "../../plugins"; -import { Provider } from "../../providers"; -import { PROVIDER_LOCAL_NETWORK_CONFIG, getFaucetClient, longTestTimeout } from "../unit/test_helper.test"; - -const provider = new Provider(PROVIDER_LOCAL_NETWORK_CONFIG); -const faucetClient = getFaucetClient(); -const aptosToken = new AptosToken(provider); - -const alice = new AptosAccount(); -const bob = new AptosAccount(); - -const collectionName = "AliceCollection"; -const tokenName = "Alice Token"; -let tokenAddress = ""; - -describe("token objects", () => { - beforeAll(async () => { - // Fund Alice's Account - await faucetClient.fundAccount(alice.address(), 100000000); - }, longTestTimeout); - - test( - "create collection", - async () => { - await provider.waitForTransaction( - await aptosToken.createCollection(alice, "Alice's simple collection", collectionName, "https://aptos.dev", 5, { - royaltyNumerator: 10, - royaltyDenominator: 10, - }), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "mint", - async () => { - const txn = await provider.waitForTransactionWithResult( - await aptosToken.mint( - alice, - collectionName, - "Alice's simple token", - tokenName, - "https://aptos.dev/img/nyan.jpeg", - ["key"], - ["bool"], - ["true"], - ), - { checkSuccess: true }, - ); - tokenAddress = (txn as UserTransaction).events[0].data.token; - }, - longTestTimeout, - ); - - test( - "mint soul bound", - async () => { - await provider.waitForTransaction( - await aptosToken.mintSoulBound( - alice, - collectionName, - "Alice's simple soul bound token", - "Alice's soul bound token", - "https://aptos.dev/img/nyan.jpeg", - bob, - ["key"], - ["bool"], - ["true"], - ), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "freeze transfer", - async () => { - await provider.waitForTransaction(await aptosToken.freezeTokenTransafer(alice, tokenAddress), { - checkSuccess: true, - }); - }, - longTestTimeout, - ); - - test( - "unfreeze token transfer", - async () => { - await provider.waitForTransaction(await aptosToken.unfreezeTokenTransafer(alice, tokenAddress), { - checkSuccess: true, - }); - }, - longTestTimeout, - ); - - test( - "set token description", - async () => { - await provider.waitForTransaction( - await aptosToken.setTokenDescription(alice, tokenAddress, "my updated token description"), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "set token name", - async () => { - await provider.waitForTransaction(await aptosToken.setTokenName(alice, tokenAddress, "my updated token name"), { - checkSuccess: true, - }); - }, - longTestTimeout, - ); - - test( - "set token uri", - async () => { - await provider.waitForTransaction( - await aptosToken.setTokenName(alice, tokenAddress, "https://aptos.dev/img/hero.jpg"), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "add token property", - async () => { - await provider.waitForTransaction( - await aptosToken.addTokenProperty(alice, tokenAddress, "newKey", "BOOLEAN", "true"), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "add typed property", - async () => { - await provider.waitForTransaction( - await aptosToken.addTypedProperty(alice, tokenAddress, "newTypedKey", "VECTOR", "[hello,world]"), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "update typed property", - async () => { - await provider.waitForTransaction( - await aptosToken.updateTypedProperty(alice, tokenAddress, "newTypedKey", "U8", "2"), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "update token property", - async () => { - await provider.waitForTransaction( - await aptosToken.updateTokenProperty(alice, tokenAddress, "newKey", "U8", "5"), - { checkSuccess: true }, - ); - }, - longTestTimeout, - ); - - test( - "remove token property", - async () => { - await provider.waitForTransaction(await aptosToken.removeTokenProperty(alice, tokenAddress, "newKey"), { - checkSuccess: true, - }); - }, - longTestTimeout, - ); - - test( - "transfer token ownership", - async () => { - await provider.waitForTransaction(await aptosToken.transferTokenOwnership(alice, tokenAddress, bob.address()), { - checkSuccess: true, - }); - }, - longTestTimeout, - ); - - test( - "burn token", - async () => { - await provider.waitForTransaction(await aptosToken.burnToken(alice, tokenAddress), { checkSuccess: true }); - }, - longTestTimeout, - ); -}); diff --git a/m1/JavaScript-client/src/tests/e2e/coin_client.test.ts b/m1/JavaScript-client/src/tests/e2e/coin_client.test.ts deleted file mode 100644 index ba489becc..000000000 --- a/m1/JavaScript-client/src/tests/e2e/coin_client.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AptosClient } from "../../providers/aptos_client"; -import { getFaucetClient, longTestTimeout, NODE_URL } from "../unit/test_helper.test"; -import { AptosAccount } from "../../account/aptos_account"; -import { CoinClient } from "../../plugins/coin_client"; - -test( - "transfer and checkBalance works", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - const coinClient = new CoinClient(client); - - const alice = new AptosAccount(); - const bob = new AptosAccount(); - await faucetClient.fundAccount(alice.address(), 100_000_000); - await faucetClient.fundAccount(bob.address(), 0); - - await client.waitForTransaction(await coinClient.transfer(alice, bob, 42), { checkSuccess: true }); - - expect(await coinClient.checkBalance(bob)).toBe(BigInt(42)); - - // Test that `createReceiverIfMissing` works. - const jemima = new AptosAccount(); - await client.waitForTransaction(await coinClient.transfer(alice, jemima, 717, { createReceiverIfMissing: true }), { - checkSuccess: true, - }); - - // Check that using a string address instead of an account works with `checkBalance`. - expect(await coinClient.checkBalance(jemima.address().hex())).toBe(BigInt(717)); - }, - longTestTimeout, -); diff --git a/m1/JavaScript-client/src/tests/e2e/faucet_client.test.ts b/m1/JavaScript-client/src/tests/e2e/faucet_client.test.ts deleted file mode 100644 index d4dd6e205..000000000 --- a/m1/JavaScript-client/src/tests/e2e/faucet_client.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AptosClient } from "../../providers"; -import { FaucetClient } from "../../plugins"; -import { AptosAccount } from "../../account"; -import { HexString } from "../../utils"; -import * as Gen from "../../generated/index"; - -import { NODE_URL, getFaucetClient, longTestTimeout } from "../unit/test_helper.test"; - -const aptosCoin = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"; - -test("faucet url empty", () => { - expect(() => { - const faucetClient = new FaucetClient("http://localhost:8080", ""); - faucetClient.getAccount("0x1"); - }).toThrow("Faucet URL cannot be empty."); -}); - -test( - "full tutorial faucet flow", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - - const account1 = new AptosAccount(); - const txns = await faucetClient.fundAccount(account1.address(), 10000000); - const tx0 = await client.getTransactionByHash(txns[0]); - expect(tx0.type).toBe("user_transaction"); - let resources = await client.getAccountResources(account1.address()); - let accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as { coin: { value: string } }).coin.value).toBe("10000000"); - - const account2 = new AptosAccount(); - await faucetClient.fundAccount(account2.address(), 0); - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as { coin: { value: string } }).coin.value).toBe("0"); - - const payload: Gen.TransactionPayload_EntryFunctionPayload = { - type: "entry_function_payload", - function: "0x1::coin::transfer", - type_arguments: ["0x1::aptos_coin::AptosCoin"], - arguments: [account2.address().hex(), 717], - }; - - const txnRequest = await client.generateTransaction(account1.address(), payload, { max_gas_amount: "2000" }); - const signedTxn = await client.signTransaction(account1, txnRequest); - const transactionRes = await client.submitTransaction(signedTxn); - const txn = await client.waitForTransactionWithResult(transactionRes.hash); - expect((txn as any)?.success).toBe(true); - - resources = await client.getAccountResources(account2.address()); - accountResource = resources.find((r) => r.type === aptosCoin); - expect((accountResource!.data as { coin: { value: string } }).coin.value).toBe("717"); - - const res = await client.getAccountTransactions(account1.address(), { start: BigInt(0) }); - const tx = res.find((e) => e.type === "user_transaction") as Gen.UserTransaction; - expect(new HexString(tx.sender).toShortString()).toBe(account1.address().toShortString()); - - const events = await client.getEventsByEventHandle(tx.sender, aptosCoin, "withdraw_events"); - expect(events[0].type).toBe("0x1::coin::WithdrawEvent"); - - const eventSubset = await client.getEventsByEventHandle(tx.sender, aptosCoin, "withdraw_events", { - start: BigInt(0), - limit: 1, - }); - expect(eventSubset[0].type).toBe("0x1::coin::WithdrawEvent"); - - const events2 = await client.getEventsByCreationNumber( - events[0].guid.account_address, - events[0].guid.creation_number, - ); - expect(events2[0].type).toBe("0x1::coin::WithdrawEvent"); - }, - longTestTimeout, -); diff --git a/m1/JavaScript-client/src/tests/e2e/indexer.test.ts b/m1/JavaScript-client/src/tests/e2e/indexer.test.ts deleted file mode 100644 index d62a55bd6..000000000 --- a/m1/JavaScript-client/src/tests/e2e/indexer.test.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { AptosAccount } from "../../account/aptos_account"; -import { AptosClient } from "../../providers/aptos_client"; -import { bcsSerializeBool } from "../../bcs"; -import { FaucetClient } from "../../plugins/faucet_client"; -import { IndexerClient } from "../../providers/indexer"; -import { TokenClient } from "../../plugins/token_client"; -import { FAUCET_AUTH_TOKEN, longTestTimeout } from "../unit/test_helper.test"; -import { Network, NetworkToIndexerAPI, NetworkToNodeAPI, sleep } from "../../utils"; - -const aptosClient = new AptosClient(NetworkToNodeAPI[Network.TESTNET]); -const faucetClient = new FaucetClient( - "https://fullnode.testnet.aptoslabs.com", - "https://faucet.testnet.aptoslabs.com", - { TOKEN: FAUCET_AUTH_TOKEN }, -); -const tokenClient = new TokenClient(aptosClient); -const alice = new AptosAccount(); -const collectionName = "AliceCollection"; -const tokenName = "Alice Token"; -const indexerClient = new IndexerClient(NetworkToIndexerAPI[Network.TESTNET]); - -describe("Indexer", () => { - it("should throw an error when account address is not valid", async () => { - expect(async () => { - await indexerClient.getAccountNFTs("702ca08576f66393140967fef983bb6bf160dafeb73de9c4ddac4d2dc"); - }).rejects.toThrow("Address needs to be 66 chars long."); - - expect(async () => { - await indexerClient.getAccountNFTs("0x702ca08576f66393140967fef983bb6bf160dafeb73de9c4ddac4d2dc"); - }).rejects.toThrow("Address needs to be 66 chars long."); - }); - - it("should not throw an error when account address is missing 0x", async () => { - expect(async () => { - await indexerClient.getAccountNFTs("790a34c702ca08576f66393140967fef983bb6bf160dafeb73de9c4ddac4d2dc"); - }).not.toThrow("Address needs to be 66 chars long."); - }); - - beforeAll(async () => { - await faucetClient.fundAccount(alice.address(), 100000000); - // Create collection and token on Alice's account - await aptosClient.waitForTransaction( - await tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"), - { checkSuccess: true }, - ); - await aptosClient.waitForTransaction( - await tokenClient.createTokenWithMutabilityConfig( - alice, - collectionName, - tokenName, - "Alice's simple token", - 1, - "https://aptos.dev/img/nyan.jpeg", - 1000, - alice.address(), - 1, - 0, - ["TOKEN_BURNABLE_BY_OWNER"], - [bcsSerializeBool(true)], - ["bool"], - [false, false, false, false, true], - ), - { checkSuccess: true }, - ); - }, longTestTimeout); - - describe("get data", () => { - jest.retryTimes(5); - beforeEach(async () => { - await sleep(1000); - }); - it( - "gets account NFTs", - async () => { - const accountNFTs = await indexerClient.getAccountNFTs(alice.address().hex()); - expect(accountNFTs.current_token_ownerships).toHaveLength(1); - expect(accountNFTs.current_token_ownerships[0]).toHaveProperty("current_token_data"); - expect(accountNFTs.current_token_ownerships[0]).toHaveProperty("current_collection_data"); - expect(accountNFTs.current_token_ownerships[0].current_token_data?.name).toBe("Alice Token"); - }, - longTestTimeout, - ); - - it( - "gets token activities", - async () => { - const accountNFTs = await indexerClient.getAccountNFTs(alice.address().hex()); - const tokenActivity = await indexerClient.getTokenActivities( - accountNFTs.current_token_ownerships[0].current_token_data!.token_data_id_hash, - ); - expect(tokenActivity.token_activities).toHaveLength(2); - expect(tokenActivity.token_activities[0]).toHaveProperty("from_address"); - expect(tokenActivity.token_activities[0]).toHaveProperty("to_address"); - }, - longTestTimeout, - ); - - it( - "gets account coin data", - async () => { - const accountCoinData = await indexerClient.getAccountCoinsData(alice.address().hex()); - expect(accountCoinData.current_coin_balances[0].coin_type).toEqual("0x1::aptos_coin::AptosCoin"); - }, - longTestTimeout, - ); - - it( - "gets account token count", - async () => { - const accountTokenCount = await indexerClient.getAccountTokensCount(alice.address().hex()); - expect(accountTokenCount.current_token_ownerships_aggregate.aggregate?.count).toEqual(1); - }, - longTestTimeout, - ); - - it( - "gets account transactions count", - async () => { - const accountTransactionsCount = await indexerClient.getAccountTransactionsCount(alice.address().hex()); - expect(accountTransactionsCount.move_resources_aggregate.aggregate?.count).toEqual(3); - }, - longTestTimeout, - ); - - it( - "gets account transactions data", - async () => { - const accountTransactionsData = await indexerClient.getAccountTransactionsData(alice.address().hex()); - expect(accountTransactionsData.move_resources[0]).toHaveProperty("transaction_version"); - }, - longTestTimeout, - ); - - it( - "gets token activities count", - async () => { - const accountNFTs = await indexerClient.getAccountNFTs(alice.address().hex()); - const tokenActivitiesCount = await indexerClient.getTokenActivitiesCount( - accountNFTs.current_token_ownerships[0].current_token_data!.token_data_id_hash, - ); - expect(tokenActivitiesCount.token_activities_aggregate.aggregate?.count).toBe(2); - }, - longTestTimeout, - ); - - it( - "gets token data", - async () => { - const accountNFTs = await indexerClient.getAccountNFTs(alice.address().hex()); - const tokenData = await indexerClient.getTokenData( - accountNFTs.current_token_ownerships[0].current_token_data!.token_data_id_hash, - ); - expect(tokenData.current_token_datas[0].name).toEqual("Alice Token"); - }, - longTestTimeout, - ); - - it( - "gets token owners data", - async () => { - const accountNFTs = await indexerClient.getAccountNFTs(alice.address().hex()); - const tokenOwnersData = await indexerClient.getTokenOwnersData( - accountNFTs.current_token_ownerships[0].current_token_data!.token_data_id_hash, - 0, - ); - expect(tokenOwnersData.current_token_ownerships[0].owner_address).toEqual(alice.address().hex()); - }, - longTestTimeout, - ); - - it( - "gets top user transactions", - async () => { - const topUserTransactions = await indexerClient.getTopUserTransactions(5); - expect(topUserTransactions.user_transactions.length).toEqual(5); - }, - longTestTimeout, - ); - - it( - "gets user transactions", - async () => { - const userTransactions = await indexerClient.getUserTransactions(482294669, { limit: 4 }); - expect(userTransactions.user_transactions[0].version).toEqual(482294669); - expect(userTransactions.user_transactions.length).toEqual(4); - }, - longTestTimeout, - ); - - test("gets indexer ledger info", async () => { - const ledgerInfo = await indexerClient.getIndexerLedgerInfo(); - expect(ledgerInfo.ledger_infos[0].chain_id).toBeGreaterThan(1); - }); - }); -}); diff --git a/m1/JavaScript-client/src/tests/e2e/provider.test.ts b/m1/JavaScript-client/src/tests/e2e/provider.test.ts deleted file mode 100644 index d9667bfb2..000000000 --- a/m1/JavaScript-client/src/tests/e2e/provider.test.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { AptosAccount } from "../../account/aptos_account"; -import { AptosClient } from "../../providers/aptos_client"; -import { bcsSerializeBool } from "../../bcs"; -import { Provider } from "../../providers/provider"; -import { FaucetClient } from "../../plugins/faucet_client"; -import { TokenClient } from "../../plugins/token_client"; -import { Network, NetworkToIndexerAPI, NetworkToNodeAPI, sleep } from "../../utils"; -import { FAUCET_AUTH_TOKEN, longTestTimeout } from "../unit/test_helper.test"; - -describe("Provider", () => { - const faucetClient = new FaucetClient( - "https://fullnode.testnet.aptoslabs.com", - "https://faucet.testnet.aptoslabs.com", - { TOKEN: FAUCET_AUTH_TOKEN }, - ); - const alice = new AptosAccount(); - - it("uses provided network as API", async () => { - const provider = new Provider(Network.TESTNET); - expect(provider.aptosClient.nodeUrl).toBe(NetworkToNodeAPI[Network.TESTNET]); - expect(provider.indexerClient.endpoint).toBe(NetworkToIndexerAPI[Network.TESTNET]); - }); - - it("uses custom endpoints as API", async () => { - const provider = new Provider({ fullnodeUrl: "full-node-url", indexerUrl: "indexer-url" }); - expect(provider.aptosClient.nodeUrl).toBe("full-node-url/v1"); - expect(provider.indexerClient.endpoint).toBe("indexer-url"); - }); - - it("throws error when endpoint not provided", async () => { - expect(() => { - new Provider({ fullnodeUrl: "", indexerUrl: "" }); - }).toThrow("network is not provided"); - }); - - describe("requests", () => { - beforeAll(async () => { - await faucetClient.fundAccount(alice.address(), 100000000); - }); - - describe("query full node", () => { - it("gets genesis account from fullnode", async () => { - const provider = new Provider(Network.TESTNET); - const genesisAccount = await provider.getAccount("0x1"); - expect(genesisAccount.authentication_key.length).toBe(66); - expect(genesisAccount.sequence_number).not.toBeNull(); - }); - }); - - describe("query indexer", () => { - const aptosClient = new AptosClient("https://fullnode.testnet.aptoslabs.com"); - const tokenClient = new TokenClient(aptosClient); - const collectionName = "AliceCollection"; - const tokenName = "Alice Token"; - - beforeAll(async () => { - // Create collection and token on Alice's account - await aptosClient.waitForTransaction( - await tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"), - { checkSuccess: true }, - ); - - await aptosClient.waitForTransaction( - await tokenClient.createTokenWithMutabilityConfig( - alice, - collectionName, - tokenName, - "Alice's simple token", - 1, - "https://aptos.dev/img/nyan.jpeg", - 1000, - alice.address(), - 1, - 0, - ["TOKEN_BURNABLE_BY_OWNER"], - [bcsSerializeBool(true)], - ["bool"], - [false, false, false, false, true], - ), - { checkSuccess: true }, - ); - }, longTestTimeout); - - jest.retryTimes(5); - beforeEach(async () => { - await sleep(1000); - }); - - it("gets account NFTs from indexer", async () => { - let provider = new Provider(Network.TESTNET); - const accountNFTs = await provider.getAccountNFTs(alice.address().hex(), { limit: 20, offset: 0 }); - expect(accountNFTs.current_token_ownerships).toHaveLength(1); - expect(accountNFTs.current_token_ownerships[0]).toHaveProperty("current_token_data"); - expect(accountNFTs.current_token_ownerships[0]).toHaveProperty("current_collection_data"); - expect(accountNFTs.current_token_ownerships[0].current_token_data?.name).toBe("Alice Token"); - }); - }); - }); -}); diff --git a/m1/JavaScript-client/src/tests/e2e/token_client.test.ts b/m1/JavaScript-client/src/tests/e2e/token_client.test.ts deleted file mode 100644 index 930b0cc21..000000000 --- a/m1/JavaScript-client/src/tests/e2e/token_client.test.ts +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AptosAccount } from "../../account/aptos_account"; -import { AptosClient } from "../../providers/aptos_client"; -import { TokenClient } from "../../plugins/token_client"; - -import { getFaucetClient, longTestTimeout, NODE_URL } from "../unit/test_helper.test"; -import { bcsSerializeBool } from "../../bcs"; - -test( - "full tutorial nft token flow", - async () => { - const client = new AptosClient(NODE_URL); - const faucetClient = getFaucetClient(); - const tokenClient = new TokenClient(client); - - const alice = new AptosAccount(); - const bob = new AptosAccount(); - - // Fund both Alice's and Bob's Account - await faucetClient.fundAccount(alice.address(), 100000000); - await faucetClient.fundAccount(bob.address(), 100000000); - - const collectionName = "AliceCollection"; - const tokenName = "Alice Token"; - - // Create collection and token on Alice's account - await client.waitForTransaction( - await tokenClient.createCollection(alice, collectionName, "Alice's simple collection", "https://aptos.dev"), - { checkSuccess: true }, - ); - - await client.waitForTransaction( - await tokenClient.createTokenWithMutabilityConfig( - alice, - collectionName, - tokenName, - "Alice's simple token", - 2, - "https://aptos.dev/img/nyan.jpeg", - 1000, - alice.address(), - 1, - 0, - ["TOKEN_BURNABLE_BY_OWNER"], - [bcsSerializeBool(true)], - ["bool"], - [false, false, false, false, true], - ), - { checkSuccess: true }, - ); - - const tokenId = { - token_data_id: { - creator: alice.address().hex(), - collection: collectionName, - name: tokenName, - }, - property_version: "0", - }; - - // Transfer Token from Alice's Account to Bob's Account - await tokenClient.getCollectionData(alice.address().hex(), collectionName); - let aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId); - expect(aliceBalance.amount).toBe("2"); - const tokenData = await tokenClient.getTokenData(alice.address().hex(), collectionName, tokenName); - expect(tokenData.name).toBe(tokenName); - - await client.waitForTransaction( - await tokenClient.offerToken(alice, bob.address().hex(), alice.address().hex(), collectionName, tokenName, 1), - { checkSuccess: true }, - ); - aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId); - expect(aliceBalance.amount).toBe("1"); - - await client.waitForTransaction( - await tokenClient.cancelTokenOffer(alice, bob.address().hex(), alice.address().hex(), collectionName, tokenName), - { checkSuccess: true }, - ); - aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId); - expect(aliceBalance.amount).toBe("2"); - - await client.waitForTransaction( - await tokenClient.offerToken(alice, bob.address().hex(), alice.address().hex(), collectionName, tokenName, 1), - { checkSuccess: true }, - ); - aliceBalance = await tokenClient.getTokenForAccount(alice.address().hex(), tokenId); - expect(aliceBalance.amount).toBe("1"); - - await client.waitForTransaction( - await tokenClient.claimToken(bob, alice.address().hex(), alice.address().hex(), collectionName, tokenName), - { checkSuccess: true }, - ); - - const bobBalance = await tokenClient.getTokenForAccount(bob.address().hex(), tokenId); - expect(bobBalance.amount).toBe("1"); - - // default token property is configured to be mutable and then alice can make bob burn token after token creation - // test mutate Bob's token properties and allow owner to burn this token - let a = await tokenClient.mutateTokenProperties( - alice, - bob.address(), - alice.address(), - collectionName, - tokenName, - 0, - 1, - ["test"], - [bcsSerializeBool(true)], - ["bool"], - ); - await client.waitForTransactionWithResult(a); - - const newTokenId = { - token_data_id: { - creator: alice.address().hex(), - collection: collectionName, - name: tokenName, - }, - property_version: "1", - }; - const mutated_token = await tokenClient.getTokenForAccount(bob.address().hex(), newTokenId); - // expect property map deserialization works - expect(mutated_token.token_properties.data["test"].value).toBe("true"); - expect(mutated_token.token_properties.data["TOKEN_BURNABLE_BY_OWNER"].value).toBe("true"); - - // burn the token by owner - var txn_hash = await tokenClient.burnByOwner(bob, alice.address(), collectionName, tokenName, 1, 1); - await client.waitForTransactionWithResult(txn_hash); - const newbalance = await tokenClient.getTokenForAccount(bob.address().hex(), newTokenId); - expect(newbalance.amount).toBe("0"); - - //bob opt_in directly transfer and alice transfer token to bob directly - txn_hash = await tokenClient.optInTokenTransfer(bob, true); - await client.waitForTransactionWithResult(txn_hash); - - // alice still have one token with property version 0. - txn_hash = await tokenClient.transferWithOptIn( - alice, - alice.address(), - collectionName, - tokenName, - 0, - bob.address(), - 1, - ); - await client.waitForTransactionWithResult(txn_hash); - const balance = await tokenClient.getTokenForAccount(bob.address().hex(), tokenId); - expect(balance.amount).toBe("1"); - }, - longTestTimeout, -); diff --git a/m1/JavaScript-client/src/tests/unit/abi.test.ts b/m1/JavaScript-client/src/tests/unit/abi.test.ts deleted file mode 100644 index 3755e7967..000000000 --- a/m1/JavaScript-client/src/tests/unit/abi.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { HexString } from "../../utils"; -import { Deserializer, Serializer } from "../../bcs"; -import { ScriptABI, EntryFunctionABI, TransactionScriptABI, ArgumentABI } from "../../aptos_types/abi"; -import { TypeTagAddress, TypeTagU64 } from "../../aptos_types"; -import { ModuleId } from "../../aptos_types"; - -// eslint-disable-next-line operator-linebreak -const SCRIPT_FUNCTION_ABI = - // eslint-disable-next-line max-len - "010E6372656174655F6163636F756E740000000000000000000000000000000000000000000000000000000000000001074163636F756E7420204261736963206163636F756E74206372656174696F6E206D6574686F64732E000108617574685F6B657904"; - -// eslint-disable-next-line operator-linebreak -const TRANSACTION_SCRIPT_ABI = - // eslint-disable-next-line max-len - "00046D61696E0F20412074657374207363726970742E8B01A11CEB0B050000000501000403040A050E0B071924083D200000000101020301000003010400020C0301050001060C0101074163636F756E74065369676E65720A616464726573735F6F66096578697374735F617400000000000000000000000000000000000000000000000000000000000000010000010A0E0011000C020B021101030705090B0127020001016902"; - -describe("ABI", () => { - it("parses create_account successfully", async () => { - const name = "create_account"; - const doc = " Basic account creation methods."; - const typeArgABIs = [new ArgumentABI("auth_key", new TypeTagAddress())]; - - const abi = new EntryFunctionABI(name, ModuleId.fromStr("0x1::Account"), doc, [], typeArgABIs); - const serializer = new Serializer(); - abi.serialize(serializer); - expect(HexString.fromUint8Array(serializer.getBytes()).noPrefix()).toBe(SCRIPT_FUNCTION_ABI.toLowerCase()); - - const deserializer = new Deserializer(new HexString(SCRIPT_FUNCTION_ABI).toUint8Array()); - const entryFunctionABI = ScriptABI.deserialize(deserializer) as EntryFunctionABI; - const { address: moduleAddress, name: moduleName } = entryFunctionABI.module_name; - expect(entryFunctionABI.name).toBe("create_account"); - expect(HexString.fromUint8Array(moduleAddress.address).toShortString()).toBe("0x1"); - expect(moduleName.value).toBe("Account"); - expect(entryFunctionABI.doc.trim()).toBe("Basic account creation methods."); - - const arg = entryFunctionABI.args[0]; - expect(arg.name).toBe("auth_key"); - expect(arg.type_tag instanceof TypeTagAddress).toBeTruthy(); - }); - - it("parses script abi successfully", async () => { - const name = "main"; - // eslint-disable-next-line max-len - const code = - "0xa11ceb0b050000000501000403040a050e0b071924083d200000000101020301000003010400020c0301050001060c0101074163636f756e74065369676e65720a616464726573735f6f66096578697374735f617400000000000000000000000000000000000000000000000000000000000000010000010a0e0011000c020b021101030705090b012702"; - const doc = " A test script."; - const typeArgABIs = [new ArgumentABI("i", new TypeTagU64())]; - const abi = new TransactionScriptABI(name, doc, HexString.ensure(code).toUint8Array(), [], typeArgABIs); - const serializer = new Serializer(); - abi.serialize(serializer); - expect(HexString.fromUint8Array(serializer.getBytes()).noPrefix()).toBe(TRANSACTION_SCRIPT_ABI.toLowerCase()); - - const deserializer = new Deserializer(new HexString(TRANSACTION_SCRIPT_ABI).toUint8Array()); - const transactionScriptABI = ScriptABI.deserialize(deserializer) as TransactionScriptABI; - expect(transactionScriptABI.name).toBe("main"); - expect(transactionScriptABI.doc.trim()).toBe("A test script."); - - expect(HexString.fromUint8Array(transactionScriptABI.code).hex()).toBe(code); - - const arg = transactionScriptABI.args[0]; - expect(arg.name).toBe("i"); - expect(arg.type_tag instanceof TypeTagU64).toBeTruthy(); - }); -}); diff --git a/m1/JavaScript-client/src/tests/unit/account_address.test.ts b/m1/JavaScript-client/src/tests/unit/account_address.test.ts deleted file mode 100644 index 687c531f8..000000000 --- a/m1/JavaScript-client/src/tests/unit/account_address.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AccountAddress } from "../../aptos_types"; - -const ADDRESS_LONG = "000000000000000000000000000000000000000000000000000000000a550c18"; -const ADDRESS_SHORT = "a550c18"; - -describe("AccountAddress", () => { - it("gets created from full hex string", async () => { - const addr = AccountAddress.fromHex(ADDRESS_LONG); - expect(Buffer.from(addr.address).toString("hex")).toBe(ADDRESS_LONG); - }); - - it("gets created from short hex string", async () => { - const addr = AccountAddress.fromHex(ADDRESS_SHORT); - expect(Buffer.from(addr.address).toString("hex")).toBe(ADDRESS_LONG); - }); - - it("gets created from prefixed full hex string", async () => { - const addr = AccountAddress.fromHex(`0x${ADDRESS_LONG}`); - expect(Buffer.from(addr.address).toString("hex")).toBe(ADDRESS_LONG); - }); - - it("gets created from prefixed short hex string", async () => { - const addr = AccountAddress.fromHex(`0x${ADDRESS_SHORT}`); - expect(Buffer.from(addr.address).toString("hex")).toBe(ADDRESS_LONG); - }); - - it("gets created from prefixed short hex string with leading 0s", async () => { - const addr = AccountAddress.fromHex(`0x000${ADDRESS_SHORT}`); - expect(Buffer.from(addr.address).toString("hex")).toBe(ADDRESS_LONG); - }); - - it("throws exception when initiating from a long hex string", async () => { - expect(() => { - AccountAddress.fromHex(`1${ADDRESS_LONG}`); - // eslint-disable-next-line quotes - }).toThrow("Hex string is too long. Address's length is 32 bytes."); - }); - - it("throws exception when initiating from a long hex string", async () => { - expect(() => { - AccountAddress.fromHex(`1${ADDRESS_LONG}`); - // eslint-disable-next-line quotes - }).toThrow("Hex string is too long. Address's length is 32 bytes."); - }); - - it("isValid short with 0x", async () => { - expect(AccountAddress.isValid(`0x${ADDRESS_SHORT}`)).toBe(true); - }); - - it("isValid short with leading 0s 0x", async () => { - expect(AccountAddress.isValid(`0x000${ADDRESS_SHORT}`)).toBe(true); - }); - - it("isValid short with leading 0s 0x", async () => { - expect(AccountAddress.isValid(`0x000${ADDRESS_SHORT}`)).toBe(true); - }); - - it("isValid long with leading 0s without 0x", async () => { - expect(AccountAddress.isValid(`${ADDRESS_LONG}`)).toBe(true); - }); - - it("isValid long with leading 0s with 0x", async () => { - expect(AccountAddress.isValid(`0x${ADDRESS_LONG}`)).toBe(true); - }); - - it("not isValid empty string", async () => { - expect(AccountAddress.isValid("")).toBe(false); - }); - - it("not isValid too long without 0x", async () => { - expect(AccountAddress.isValid(`00${ADDRESS_LONG}`)).toBe(false); - }); - - it("not isValid too long with 0x", async () => { - expect(AccountAddress.isValid(`0x00${ADDRESS_LONG}`)).toBe(false); - }); -}); diff --git a/m1/JavaScript-client/src/tests/unit/aptos_account.test.ts b/m1/JavaScript-client/src/tests/unit/aptos_account.test.ts deleted file mode 100644 index cdbaf82e0..000000000 --- a/m1/JavaScript-client/src/tests/unit/aptos_account.test.ts +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AptosAccount, AptosAccountObject, getAddressFromAccountOrAddress } from "../../account"; -import { HexString } from "../../utils"; -import nacl from "tweetnacl"; - -const aptosAccountObject: AptosAccountObject = { - address: "0x978c213990c4833df71548df7ce49d54c759d6b6d932de22b24d56060b7af2aa", - privateKeyHex: - // eslint-disable-next-line max-len - "0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5de19e5d1880cac87d57484ce9ed2e84cf0f9599f12e7cc3a52e4e7657a763f2c", - publicKeyHex: "0xde19e5d1880cac87d57484ce9ed2e84cf0f9599f12e7cc3a52e4e7657a763f2c", -}; - -const mnemonic = "shoot island position soft burden budget tooth cruel issue economy destroy above"; - -test("generates random accounts", () => { - const a1 = new AptosAccount(); - const a2 = new AptosAccount(); - expect(a1.authKey()).not.toBe(a2.authKey()); - expect(a1.address().hex()).not.toBe(a2.address().hex()); -}); - -test("generates derive path accounts", () => { - const address = "0x07968dab936c1bad187c60ce4082f307d030d780e91e694ae03aef16aba73f30"; - const a1 = AptosAccount.fromDerivePath("m/44'/637'/0'/0'/0'", mnemonic); - expect(a1.address().hex()).toBe(address); -}); - -test("generates derive path accounts", () => { - expect(() => { - AptosAccount.fromDerivePath("", mnemonic); - }).toThrow(new Error("Invalid derivation path")); -}); - -test("accepts custom address", () => { - const address = "0x777"; - const a1 = new AptosAccount(undefined, address); - expect(a1.address().hex()).toBe(address); -}); - -test("Deserializes from AptosAccountObject", () => { - const a1 = AptosAccount.fromAptosAccountObject(aptosAccountObject); - expect(a1.address().hex()).toBe(aptosAccountObject.address); - expect(a1.pubKey().hex()).toBe(aptosAccountObject.publicKeyHex); -}); - -test("Deserializes from AptosAccountObject without address", () => { - const privateKeyObject = { privateKeyHex: aptosAccountObject.privateKeyHex }; - const a1 = AptosAccount.fromAptosAccountObject(privateKeyObject); - expect(a1.address().hex()).toBe(aptosAccountObject.address); - expect(a1.pubKey().hex()).toBe(aptosAccountObject.publicKeyHex); -}); - -test("Serializes/Deserializes", () => { - const a1 = new AptosAccount(); - const a2 = AptosAccount.fromAptosAccountObject(a1.toPrivateKeyObject()); - expect(a1.authKey().hex()).toBe(a2.authKey().hex()); - expect(a1.address().hex()).toBe(a2.address().hex()); -}); - -test("Signs and verifies strings", () => { - const a1 = AptosAccount.fromAptosAccountObject(aptosAccountObject); - const messageHex = "0x7777"; - const expectedSignedMessage = - "0xc5de9e40ac00b371cd83b1c197fa5b665b7449b33cd3cdd305bb78222e06a671a49625ab9aea8a039d4bb70e275768084d62b094bc1b31964f2357b7c1af7e0d"; - expect(a1.signHexString(messageHex).hex()).toBe(expectedSignedMessage); - expect(a1.verifySignature(messageHex, expectedSignedMessage)).toBe(true); - expect(a1.verifySignature(messageHex + "00", expectedSignedMessage)).toBe(false); -}); - -test("Gets the resource account address", () => { - const sourceAddress = "0xca843279e3427144cead5e4d5999a3d0"; - const seed = new Uint8Array([1]); - - expect(AptosAccount.getResourceAccountAddress(sourceAddress, seed).hex()).toBe( - "0xcbed05b37b6981a57f535c1f5d136734df822abaf4cd30c51c9b4d60eae79d5d", - ); -}); - -test("Test getAddressFromAccountOrAddress", () => { - const account = AptosAccount.fromAptosAccountObject(aptosAccountObject); - expect(getAddressFromAccountOrAddress(aptosAccountObject.address!).toString()).toBe(aptosAccountObject.address); - expect(getAddressFromAccountOrAddress(HexString.ensure(aptosAccountObject.address!)).toString()).toBe( - aptosAccountObject.address, - ); - expect(getAddressFromAccountOrAddress(account).toString()).toBe(aptosAccountObject.address); -}); diff --git a/m1/JavaScript-client/src/tests/unit/builder.test.ts b/m1/JavaScript-client/src/tests/unit/builder.test.ts deleted file mode 100644 index 6e66ee6cc..000000000 --- a/m1/JavaScript-client/src/tests/unit/builder.test.ts +++ /dev/null @@ -1,234 +0,0 @@ -import { TransactionBuilderRemoteABI } from "../../transaction_builder"; -import { AptosClient } from "../../providers"; -import { getFaucetClient, longTestTimeout, NODE_URL } from "./test_helper.test"; -import { AptosAccount } from "../../account"; -import { - RawTransaction, - TransactionPayloadEntryFunction, - TypeTagBool, - TypeTagStruct, - TypeTagU8, - TypeTagVector, -} from "../../aptos_types"; -import { HexString } from "../../utils"; - -describe.only("TransactionBuilderRemoteABI", () => { - test( - "generates raw txn from an entry function", - async () => { - const client = new AptosClient(NODE_URL); - const alice = new AptosAccount(); - const faucetClient = getFaucetClient(); - await faucetClient.fundAccount(alice.address(), 100000000); - // Create an instance of the class - const builder = new TransactionBuilderRemoteABI(client, { sender: alice.address() }); - - // Spy on the fetchABI method - const fetchABISpy = jest.spyOn(builder, "fetchABI"); - - // Mock the implementation of the fetchABI method to return a mock data - const abi = new Map(); - abi.set("0x1::some_modules::SomeName", { - fullName: "0x1::some_modules::SomeName", - name: "SomeName", - is_entry: true, - is_view: false, - generic_type_params: [], - params: ["&signer", "0x1::string::String"], - return: [], - visibility: "public", - }); - fetchABISpy.mockResolvedValue(abi); - - // Call the build method with some arguments - const rawTxn = await builder.build("0x1::some_modules::SomeName", [], ["key"]); - expect(rawTxn instanceof RawTransaction).toBeTruthy(); - expect(rawTxn.sender.address).toEqual(new HexString(alice.address().hex()).toUint8Array()); - expect(rawTxn.payload instanceof TransactionPayloadEntryFunction).toBeTruthy(); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.module_name.name.value).toBe("some_modules"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.function_name.value).toBe("SomeName"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args).toHaveLength(0); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.args).toHaveLength(1); - - // Restore the original implementation of the fetch method - fetchABISpy.mockRestore(); - }, - longTestTimeout, - ); - - test( - "generates raw txn from an entry function with Object type", - async () => { - const client = new AptosClient(NODE_URL); - const alice = new AptosAccount(); - const faucetClient = getFaucetClient(); - await faucetClient.fundAccount(alice.address(), 100000000); - // Create an instance of the class - const builder = new TransactionBuilderRemoteABI(client, { sender: alice.address() }); - - // Spy on the fetchABI method - const fetchABISpy = jest.spyOn(builder, "fetchABI"); - - // Mock the implementation of the fetchABI method to return a mock data - const abi = new Map(); - abi.set("0x1::some_modules::SomeName", { - fullName: "0x1::some_modules::SomeName", - name: "SomeName", - is_entry: true, - is_view: false, - generic_type_params: [ - { - constraints: ["key"], - }, - ], - params: ["&signer", "0x1::object::Object", "0x1::string::String"], - return: [], - visibility: "public", - }); - fetchABISpy.mockResolvedValue(abi); - - // Call the build method with some arguments - const rawTxn = await builder.build( - "0x1::some_modules::SomeName", - ["0x1::type::SomeType"], - ["0x2b4d540735a4e128fda896f988415910a45cab41c9ddd802b32dd16e8f9ca3cd", "key"], - ); - - expect(rawTxn instanceof RawTransaction).toBeTruthy(); - expect(rawTxn.sender.address).toEqual(new HexString(alice.address().hex()).toUint8Array()); - expect(rawTxn.payload instanceof TransactionPayloadEntryFunction).toBeTruthy(); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.module_name.name.value).toBe("some_modules"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.function_name.value).toBe("SomeName"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args).toHaveLength(1); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.args).toHaveLength(2); - - // Restore the original implementation of the fetch method - fetchABISpy.mockRestore(); - }, - longTestTimeout, - ); - - test( - "generates raw txn from a generic entry function", - async () => { - const client = new AptosClient(NODE_URL); - const alice = new AptosAccount(); - const faucetClient = getFaucetClient(); - await faucetClient.fundAccount(alice.address(), 100000000); - // Create an instance of the class - const builder = new TransactionBuilderRemoteABI(client, { sender: alice.address() }); - - // Spy on the fetchABI method - const fetchABISpy = jest.spyOn(builder, "fetchABI"); - - // Mock the implementation of the fetchABI method to return a mock data - const abi = new Map(); - abi.set("0x1::some_modules::SomeName", { - fullName: "0x1::some_modules::SomeName", - name: "SomeName", - is_entry: true, - is_view: false, - generic_type_params: [ - { - constraints: ["key"], - }, - { - constraints: ["drop"], - }, - ], - params: ["&signer", "0x1::object::Object", "0x1::string::String", "T1"], - return: [], - visibility: "public", - }); - fetchABISpy.mockResolvedValue(abi); - - // Call the build method with some arguments - const rawTxn = await builder.build( - "0x1::some_modules::SomeName", - ["0x1::type::SomeType", "vector"], - ["0x2b4d540735a4e128fda896f988415910a45cab41c9ddd802b32dd16e8f9ca3cd", "key", "[hello,world]"], - ); - - expect(rawTxn instanceof RawTransaction).toBeTruthy(); - expect(rawTxn.sender.address).toEqual(new HexString(alice.address().hex()).toUint8Array()); - expect(rawTxn.payload instanceof TransactionPayloadEntryFunction).toBeTruthy(); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.module_name.name.value).toBe("some_modules"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.function_name.value).toBe("SomeName"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args).toHaveLength(2); - expect( - (rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args[0] instanceof TypeTagStruct, - ).toBeTruthy(); - expect( - (rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args[1] instanceof TypeTagVector, - ).toBeTruthy(); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.args).toHaveLength(3); - - // Restore the original implementation of the fetch method - fetchABISpy.mockRestore(); - }, - longTestTimeout, - ); - - test( - "generates raw txn from an entry function with multiple generic params", - async () => { - const client = new AptosClient(NODE_URL); - const alice = new AptosAccount(); - const faucetClient = getFaucetClient(); - await faucetClient.fundAccount(alice.address(), 100000000); - // Create an instance of the class - const builder = new TransactionBuilderRemoteABI(client, { sender: alice.address() }); - - // Spy on the fetchABI method - const fetchABISpy = jest.spyOn(builder, "fetchABI"); - - // Mock the implementation of the fetchABI method to return a mock data - const abi = new Map(); - abi.set("0x1::some_modules::SomeName", { - fullName: "0x1::some_modules::SomeName", - name: "SomeName", - is_entry: true, - is_view: false, - generic_type_params: [ - { - constraints: ["key"], - }, - { - constraints: ["drop"], - }, - { - constraints: ["key"], - }, - ], - params: ["&signer", "T0", "0x1::string::String", "T1", "T2"], - return: [], - visibility: "public", - }); - fetchABISpy.mockResolvedValue(abi); - - // Call the build method with some arguments - const rawTxn = await builder.build( - "0x1::some_modules::SomeName", - ["bool", "vector", "u8"], - ["true", "key", "[hello,world]", "6"], - ); - - expect(rawTxn instanceof RawTransaction).toBeTruthy(); - expect(rawTxn.sender.address).toEqual(new HexString(alice.address().hex()).toUint8Array()); - expect(rawTxn.payload instanceof TransactionPayloadEntryFunction).toBeTruthy(); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.module_name.name.value).toBe("some_modules"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.function_name.value).toBe("SomeName"); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args).toHaveLength(3); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args[0] instanceof TypeTagBool).toBeTruthy(); - expect( - (rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args[1] instanceof TypeTagVector, - ).toBeTruthy(); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.ty_args[2] instanceof TypeTagU8).toBeTruthy(); - expect((rawTxn.payload as TransactionPayloadEntryFunction).value.args).toHaveLength(4); - - // Restore the original implementation of the fetch method - fetchABISpy.mockRestore(); - }, - longTestTimeout, - ); -}); diff --git a/m1/JavaScript-client/src/tests/unit/builder_utils.test.ts b/m1/JavaScript-client/src/tests/unit/builder_utils.test.ts deleted file mode 100644 index 885765d29..000000000 --- a/m1/JavaScript-client/src/tests/unit/builder_utils.test.ts +++ /dev/null @@ -1,399 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { HexString } from "../../utils"; -import { - AccountAddress, - Identifier, - StructTag, - TransactionArgumentAddress, - TransactionArgumentBool, - TransactionArgumentU128, - TransactionArgumentU64, - TransactionArgumentU8, - TransactionArgumentU8Vector, - TypeTagAddress, - TypeTagBool, - TypeTagParser, - TypeTagStruct, - TypeTagU128, - TypeTagU16, - TypeTagU256, - TypeTagU32, - TypeTagU64, - TypeTagU8, - TypeTagVector, -} from "../../aptos_types"; -import { Serializer } from "../../bcs"; -import { - argToTransactionArgument, - serializeArg, - ensureBoolean, - ensureNumber, - ensureBigInt, -} from "../../transaction_builder/builder_utils"; - -describe("BuilderUtils", () => { - it("parses a bool TypeTag", async () => { - expect(new TypeTagParser("bool").parseTypeTag() instanceof TypeTagBool).toBeTruthy(); - }); - - it("parses a u8 TypeTag", async () => { - expect(new TypeTagParser("u8").parseTypeTag() instanceof TypeTagU8).toBeTruthy(); - }); - - it("parses a u16 TypeTag", async () => { - expect(new TypeTagParser("u16").parseTypeTag() instanceof TypeTagU16).toBeTruthy(); - }); - - it("parses a u32 TypeTag", async () => { - expect(new TypeTagParser("u32").parseTypeTag() instanceof TypeTagU32).toBeTruthy(); - }); - - it("parses a u64 TypeTag", async () => { - expect(new TypeTagParser("u64").parseTypeTag() instanceof TypeTagU64).toBeTruthy(); - }); - - it("parses a u128 TypeTag", async () => { - expect(new TypeTagParser("u128").parseTypeTag() instanceof TypeTagU128).toBeTruthy(); - }); - - it("parses a u256 TypeTag", async () => { - expect(new TypeTagParser("u256").parseTypeTag() instanceof TypeTagU256).toBeTruthy(); - }); - - it("parses a address TypeTag", async () => { - expect(new TypeTagParser("address").parseTypeTag() instanceof TypeTagAddress).toBeTruthy(); - }); - - it("parses a vector TypeTag", async () => { - const vectorAddress = new TypeTagParser("vector
").parseTypeTag(); - expect(vectorAddress instanceof TypeTagVector).toBeTruthy(); - expect((vectorAddress as TypeTagVector).value instanceof TypeTagAddress).toBeTruthy(); - - const vectorU64 = new TypeTagParser(" vector < u64 > ").parseTypeTag(); - expect(vectorU64 instanceof TypeTagVector).toBeTruthy(); - expect((vectorU64 as TypeTagVector).value instanceof TypeTagU64).toBeTruthy(); - }); - - it("parses a sturct TypeTag", async () => { - const assertStruct = (struct: TypeTagStruct, accountAddress: string, moduleName: string, structName: string) => { - expect(HexString.fromUint8Array(struct.value.address.address).toShortString()).toBe(accountAddress); - expect(struct.value.module_name.value).toBe(moduleName); - expect(struct.value.name.value).toBe(structName); - }; - const coin = new TypeTagParser("0x1::test_coin::Coin").parseTypeTag(); - expect(coin instanceof TypeTagStruct).toBeTruthy(); - assertStruct(coin as TypeTagStruct, "0x1", "test_coin", "Coin"); - - const aptosCoin = new TypeTagParser( - "0x1::coin::CoinStore < 0x1::test_coin::AptosCoin1 , 0x1::test_coin::AptosCoin2 > ", - ).parseTypeTag(); - expect(aptosCoin instanceof TypeTagStruct).toBeTruthy(); - assertStruct(aptosCoin as TypeTagStruct, "0x1", "coin", "CoinStore"); - - const aptosCoinTrailingComma = new TypeTagParser( - "0x1::coin::CoinStore < 0x1::test_coin::AptosCoin1 , 0x1::test_coin::AptosCoin2, > ", - ).parseTypeTag(); - expect(aptosCoinTrailingComma instanceof TypeTagStruct).toBeTruthy(); - assertStruct(aptosCoinTrailingComma as TypeTagStruct, "0x1", "coin", "CoinStore"); - - const structTypeTags = (aptosCoin as TypeTagStruct).value.type_args; - expect(structTypeTags.length).toBe(2); - - const structTypeTag1 = structTypeTags[0]; - assertStruct(structTypeTag1 as TypeTagStruct, "0x1", "test_coin", "AptosCoin1"); - - const structTypeTag2 = structTypeTags[1]; - assertStruct(structTypeTag2 as TypeTagStruct, "0x1", "test_coin", "AptosCoin2"); - - const coinComplex = new TypeTagParser( - // eslint-disable-next-line max-len - "0x1::coin::CoinStore < 0x2::coin::LPCoin < 0x1::test_coin::AptosCoin1 , vector<0x1::test_coin::AptosCoin2 > > >", - ).parseTypeTag(); - - expect(coinComplex instanceof TypeTagStruct).toBeTruthy(); - assertStruct(coinComplex as TypeTagStruct, "0x1", "coin", "CoinStore"); - const coinComplexTypeTag = (coinComplex as TypeTagStruct).value.type_args[0]; - assertStruct(coinComplexTypeTag as TypeTagStruct, "0x2", "coin", "LPCoin"); - - expect(() => { - new TypeTagParser("0x1::test_coin").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("0x1::test_coin::CoinStore<0x1::test_coin::AptosCoin").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("0x1::test_coin::CoinStore<0x1::test_coin>").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("0x1:test_coin::AptosCoin").parseTypeTag(); - }).toThrow("Unrecognized token."); - - expect(() => { - new TypeTagParser("0x!::test_coin::AptosCoin").parseTypeTag(); - }).toThrow("Unrecognized token."); - - expect(() => { - new TypeTagParser("0x1::test_coin::AptosCoin<").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("0x1::test_coin::CoinStore<0x1::test_coin::AptosCoin,").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("0x1::<::CoinStore<0x1::test_coin::AptosCoin,").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("0x1::test_coin::><0x1::test_coin::AptosCoin,").parseTypeTag(); - }).toThrow("Invalid type tag."); - - expect(() => { - new TypeTagParser("u3").parseTypeTag(); - }).toThrow("Invalid type tag."); - }); - - it("serializes a boolean arg", async () => { - let serializer = new Serializer(); - serializeArg(true, new TypeTagBool(), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x01])); - serializer = new Serializer(); - expect(() => { - serializeArg(123, new TypeTagBool(), serializer); - }).toThrow(/Invalid arg/); - }); - - it("serializes a u8 arg", async () => { - let serializer = new Serializer(); - serializeArg(255, new TypeTagU8(), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xff])); - - serializer = new Serializer(); - expect(() => { - serializeArg("u8", new TypeTagU8(), serializer); - }).toThrow(/Invalid number string/); - }); - - it("serializes a u16 arg", async () => { - let serializer = new Serializer(); - serializeArg(0x7fff, new TypeTagU16(), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xff, 0x7f])); - - serializer = new Serializer(); - expect(() => { - serializeArg("u16", new TypeTagU16(), serializer); - }).toThrow(/Invalid number string/); - }); - - it("serializes a u32 arg", async () => { - let serializer = new Serializer(); - serializeArg(0x01020304, new TypeTagU32(), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x04, 0x03, 0x02, 0x01])); - - serializer = new Serializer(); - expect(() => { - serializeArg("u32", new TypeTagU32(), serializer); - }).toThrow(/Invalid number string/); - }); - - it("serializes a u64 arg", async () => { - let serializer = new Serializer(); - serializeArg(BigInt("18446744073709551615"), new TypeTagU64(), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])); - - serializer = new Serializer(); - expect(() => { - serializeArg("u64", new TypeTagU64(), serializer); - }).toThrow(/^Cannot convert/); - }); - - it("serializes a u128 arg", async () => { - let serializer = new Serializer(); - serializeArg(BigInt("340282366920938463463374607431768211455"), new TypeTagU128(), serializer); - expect(serializer.getBytes()).toEqual( - new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), - ); - - serializer = new Serializer(); - expect(() => { - serializeArg("u128", new TypeTagU128(), serializer); - }).toThrow(/^Cannot convert/); - }); - - it("serializes a u256 arg", async () => { - let serializer = new Serializer(); - serializeArg( - BigInt("0x0001020304050607080910111213141516171819202122232425262728293031"), - new TypeTagU256(), - serializer, - ); - expect(serializer.getBytes()).toEqual( - new Uint8Array([ - 0x31, 0x30, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, - 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - ]), - ); - - serializer = new Serializer(); - expect(() => { - serializeArg("u256", new TypeTagU256(), serializer); - }).toThrow(/^Cannot convert/); - }); - - it("serializes an AccountAddress arg", async () => { - let serializer = new Serializer(); - serializeArg("0x1", new TypeTagAddress(), serializer); - expect(HexString.fromUint8Array(serializer.getBytes()).toShortString()).toEqual("0x1"); - - serializer = new Serializer(); - serializeArg(AccountAddress.fromHex("0x1"), new TypeTagAddress(), serializer); - expect(HexString.fromUint8Array(serializer.getBytes()).toShortString()).toEqual("0x1"); - - serializer = new Serializer(); - expect(() => { - serializeArg(123456, new TypeTagAddress(), serializer); - }).toThrow("Invalid account address."); - }); - - it("serializes a vector arg", async () => { - let serializer = new Serializer(); - serializeArg([255], new TypeTagVector(new TypeTagU8()), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x1, 0xff])); - - serializer = new Serializer(); - serializeArg("abc", new TypeTagVector(new TypeTagU8()), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x3, 0x61, 0x62, 0x63])); - - serializer = new Serializer(); - serializeArg(new Uint8Array([0x61, 0x62, 0x63]), new TypeTagVector(new TypeTagU8()), serializer); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x3, 0x61, 0x62, 0x63])); - - serializer = new Serializer(); - expect(() => { - serializeArg(123456, new TypeTagVector(new TypeTagU8()), serializer); - }).toThrow("Invalid vector args."); - }); - - it("serializes a struct arg", async () => { - let serializer = new Serializer(); - serializeArg( - "abc", - new TypeTagStruct( - new StructTag(AccountAddress.fromHex("0x1"), new Identifier("string"), new Identifier("String"), []), - ), - serializer, - ); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x3, 0x61, 0x62, 0x63])); - - serializer = new Serializer(); - expect(() => { - serializeArg( - "abc", - new TypeTagStruct( - new StructTag(AccountAddress.fromHex("0x3"), new Identifier("token"), new Identifier("Token"), []), - ), - serializer, - ); - }).toThrow("The only supported struct arg is of type 0x1::string::String"); - }); - - it("throws at unrecognized arg types", async () => { - const serializer = new Serializer(); - expect(() => { - // @ts-ignore - serializeArg(123456, "unknown_type", serializer); - }).toThrow("Unsupported arg type."); - }); - - it("converts a boolean TransactionArgument", async () => { - const res = argToTransactionArgument(true, new TypeTagBool()); - expect((res as TransactionArgumentBool).value).toEqual(true); - expect(() => { - argToTransactionArgument(123, new TypeTagBool()); - }).toThrow(/Invalid arg/); - }); - - it("converts a u8 TransactionArgument", async () => { - const res = argToTransactionArgument(123, new TypeTagU8()); - expect((res as TransactionArgumentU8).value).toEqual(123); - expect(() => { - argToTransactionArgument("u8", new TypeTagBool()); - }).toThrow(/Invalid boolean string/); - }); - - it("converts a u64 TransactionArgument", async () => { - const res = argToTransactionArgument(123, new TypeTagU64()); - expect((res as TransactionArgumentU64).value).toEqual(BigInt(123)); - expect(() => { - argToTransactionArgument("u64", new TypeTagU64()); - }).toThrow(/Cannot convert/); - }); - - it("converts a u128 TransactionArgument", async () => { - const res = argToTransactionArgument(123, new TypeTagU128()); - expect((res as TransactionArgumentU128).value).toEqual(BigInt(123)); - expect(() => { - argToTransactionArgument("u128", new TypeTagU128()); - }).toThrow(/Cannot convert/); - }); - - it("converts an AccountAddress TransactionArgument", async () => { - let res = argToTransactionArgument("0x1", new TypeTagAddress()) as TransactionArgumentAddress; - expect(HexString.fromUint8Array(res.value.address).toShortString()).toEqual("0x1"); - - res = argToTransactionArgument(AccountAddress.fromHex("0x2"), new TypeTagAddress()) as TransactionArgumentAddress; - expect(HexString.fromUint8Array(res.value.address).toShortString()).toEqual("0x2"); - - expect(() => { - argToTransactionArgument(123456, new TypeTagAddress()); - }).toThrow("Invalid account address."); - }); - - it("converts a vector TransactionArgument", async () => { - const res = argToTransactionArgument( - new Uint8Array([0x1]), - new TypeTagVector(new TypeTagU8()), - ) as TransactionArgumentU8Vector; - expect(res.value).toEqual(new Uint8Array([0x1])); - - expect(() => { - argToTransactionArgument(123456, new TypeTagVector(new TypeTagU8())); - }).toThrow(/.*should be an instance of Uint8Array$/); - }); - - it("throws at unrecognized TransactionArgument types", async () => { - expect(() => { - // @ts-ignore - argToTransactionArgument(123456, "unknown_type"); - }).toThrow("Unknown type for TransactionArgument."); - }); - - it("ensures a boolean", async () => { - expect(ensureBoolean(false)).toBe(false); - expect(ensureBoolean(true)).toBe(true); - expect(ensureBoolean("true")).toBe(true); - expect(ensureBoolean("false")).toBe(false); - expect(() => ensureBoolean("True")).toThrow("Invalid boolean string."); - }); - - it("ensures a number", async () => { - expect(ensureNumber(10)).toBe(10); - expect(ensureNumber("123")).toBe(123); - expect(() => ensureNumber("True")).toThrow("Invalid number string."); - }); - - it("ensures a bigint", async () => { - expect(ensureBigInt(10)).toBe(BigInt(10)); - expect(ensureBigInt("123")).toBe(BigInt(123)); - expect(() => ensureBigInt("True")).toThrow(/^Cannot convert/); - }); -}); diff --git a/m1/JavaScript-client/src/tests/unit/deserializer.test.ts b/m1/JavaScript-client/src/tests/unit/deserializer.test.ts deleted file mode 100644 index 5baee4494..000000000 --- a/m1/JavaScript-client/src/tests/unit/deserializer.test.ts +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { Deserializer } from "../../bcs/deserializer"; - -describe("BCS Deserializer", () => { - it("deserializes a non-empty string", () => { - const deserializer = new Deserializer( - new Uint8Array([ - 24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, 0xe2, 0x89, 0xa0, 0xc2, 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, 0x88, - 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab, - ]), - ); - expect(deserializer.deserializeStr()).toBe("çå∞≠¢õß∂ƒ∫"); - }); - - it("deserializes an empty string", () => { - const deserializer = new Deserializer(new Uint8Array([0])); - expect(deserializer.deserializeStr()).toBe(""); - }); - - it("deserializes dynamic length bytes", () => { - const deserializer = new Deserializer(new Uint8Array([5, 0x41, 0x70, 0x74, 0x6f, 0x73])); - expect(deserializer.deserializeBytes()).toEqual(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73])); - }); - - it("deserializes dynamic length bytes with zero elements", () => { - const deserializer = new Deserializer(new Uint8Array([0])); - expect(deserializer.deserializeBytes()).toEqual(new Uint8Array([])); - }); - - it("deserializes fixed length bytes", () => { - const deserializer = new Deserializer(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73])); - expect(deserializer.deserializeFixedBytes(5)).toEqual(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73])); - }); - - it("deserializes fixed length bytes with zero element", () => { - const deserializer = new Deserializer(new Uint8Array([])); - expect(deserializer.deserializeFixedBytes(0)).toEqual(new Uint8Array([])); - }); - - it("deserializes a boolean value", () => { - let deserializer = new Deserializer(new Uint8Array([0x01])); - expect(deserializer.deserializeBool()).toEqual(true); - deserializer = new Deserializer(new Uint8Array([0x00])); - expect(deserializer.deserializeBool()).toEqual(false); - }); - - it("throws when dserializing a boolean with disallowed values", () => { - expect(() => { - const deserializer = new Deserializer(new Uint8Array([0x12])); - deserializer.deserializeBool(); - }).toThrow("Invalid boolean value"); - }); - - it("deserializes a uint8", () => { - const deserializer = new Deserializer(new Uint8Array([0xff])); - expect(deserializer.deserializeU8()).toEqual(255); - }); - - it("deserializes a uint16", () => { - let deserializer = new Deserializer(new Uint8Array([0xff, 0xff])); - expect(deserializer.deserializeU16()).toEqual(65535); - deserializer = new Deserializer(new Uint8Array([0x34, 0x12])); - expect(deserializer.deserializeU16()).toEqual(4660); - }); - - it("deserializes a uint32", () => { - let deserializer = new Deserializer(new Uint8Array([0xff, 0xff, 0xff, 0xff])); - expect(deserializer.deserializeU32()).toEqual(4294967295); - deserializer = new Deserializer(new Uint8Array([0x78, 0x56, 0x34, 0x12])); - expect(deserializer.deserializeU32()).toEqual(305419896); - }); - - it("deserializes a uint64", () => { - let deserializer = new Deserializer(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])); - expect(deserializer.deserializeU64()).toEqual(BigInt("18446744073709551615")); - deserializer = new Deserializer(new Uint8Array([0x00, 0xef, 0xcd, 0xab, 0x78, 0x56, 0x34, 0x12])); - expect(deserializer.deserializeU64()).toEqual(BigInt("1311768467750121216")); - }); - - it("deserializes a uint128", () => { - let deserializer = new Deserializer( - new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), - ); - expect(deserializer.deserializeU128()).toEqual(BigInt("340282366920938463463374607431768211455")); - deserializer = new Deserializer( - new Uint8Array([0x00, 0xef, 0xcd, 0xab, 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), - ); - expect(deserializer.deserializeU128()).toEqual(BigInt("1311768467750121216")); - }); - it("deserializes a uint256", () => { - let deserializer = new Deserializer( - new Uint8Array([ - 0x31, 0x30, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, - 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - ]), - ); - expect(deserializer.deserializeU256()).toEqual( - BigInt("0x0001020304050607080910111213141516171819202122232425262728293031"), - ); - }); - - it("deserializes a uleb128", () => { - let deserializer = new Deserializer(new Uint8Array([0xcd, 0xea, 0xec, 0x31])); - expect(deserializer.deserializeUleb128AsU32()).toEqual(104543565); - - deserializer = new Deserializer(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0x0f])); - expect(deserializer.deserializeUleb128AsU32()).toEqual(4294967295); - }); - - it("throws when deserializing a uleb128 with out ranged value", () => { - expect(() => { - const deserializer = new Deserializer(new Uint8Array([0x80, 0x80, 0x80, 0x80, 0x10])); - deserializer.deserializeUleb128AsU32(); - }).toThrow("Overflow while parsing uleb128-encoded uint32 value"); - }); - - it("throws when deserializing against buffer that has been drained", () => { - expect(() => { - const deserializer = new Deserializer( - new Uint8Array([ - 24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, 0xe2, 0x89, 0xa0, 0xc2, 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, - 0x88, 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab, - ]), - ); - - deserializer.deserializeStr(); - deserializer.deserializeStr(); - }).toThrow("Reached to the end of buffer"); - }); -}); diff --git a/m1/JavaScript-client/src/tests/unit/helper.test.ts b/m1/JavaScript-client/src/tests/unit/helper.test.ts deleted file mode 100644 index fc5241844..000000000 --- a/m1/JavaScript-client/src/tests/unit/helper.test.ts +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AccountAddress } from "../../aptos_types"; -import { Deserializer } from "../../bcs/deserializer"; -import { - bcsSerializeBool, - bcsSerializeBytes, - bcsSerializeFixedBytes, - bcsSerializeStr, - bcsSerializeU128, - bcsSerializeU16, - bcsSerializeU32, - bcsSerializeU8, - bcsSerializeUint64, - bcsToBytes, - deserializeVector, - serializeVector, - serializeVectorWithFunc, -} from "../../bcs/helper"; -import { Serializer } from "../../bcs/serializer"; - -test("serializes and deserializes a vector of serializables", () => { - const address0 = AccountAddress.fromHex("0x1"); - const address1 = AccountAddress.fromHex("0x2"); - - const serializer = new Serializer(); - serializeVector([address0, address1], serializer); - - const addresses: AccountAddress[] = deserializeVector(new Deserializer(serializer.getBytes()), AccountAddress); - - expect(addresses[0].address).toEqual(address0.address); - expect(addresses[1].address).toEqual(address1.address); -}); - -test("bcsToBytes", () => { - const address = AccountAddress.fromHex("0x1"); - bcsToBytes(address); - - expect(bcsToBytes(address)).toEqual( - new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), - ); -}); - -test("bcsSerializeU8", () => { - expect(bcsSerializeU8(255)).toEqual(new Uint8Array([0xff])); -}); - -test("bcsSerializeU16", () => { - expect(bcsSerializeU16(65535)).toEqual(new Uint8Array([0xff, 0xff])); -}); - -test("bcsSerializeU32", () => { - expect(bcsSerializeU32(4294967295)).toEqual(new Uint8Array([0xff, 0xff, 0xff, 0xff])); -}); - -test("bcsSerializeU64", () => { - expect(bcsSerializeUint64(BigInt("18446744073709551615"))).toEqual( - new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), - ); -}); - -test("bcsSerializeU128", () => { - expect(bcsSerializeU128(BigInt("340282366920938463463374607431768211455"))).toEqual( - new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), - ); -}); - -test("bcsSerializeBool", () => { - expect(bcsSerializeBool(true)).toEqual(new Uint8Array([0x01])); -}); - -test("bcsSerializeStr", () => { - expect(bcsSerializeStr("çå∞≠¢õß∂ƒ∫")).toEqual( - new Uint8Array([ - 24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, 0xe2, 0x89, 0xa0, 0xc2, 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, 0x88, - 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab, - ]), - ); -}); - -test("bcsSerializeBytes", () => { - expect(bcsSerializeBytes(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73]))).toEqual( - new Uint8Array([5, 0x41, 0x70, 0x74, 0x6f, 0x73]), - ); -}); - -test("bcsSerializeFixedBytes", () => { - expect(bcsSerializeFixedBytes(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73]))).toEqual( - new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73]), - ); -}); - -test("serializeVectorWithFunc", () => { - expect(serializeVectorWithFunc([false, true], "serializeBool")).toEqual(new Uint8Array([0x2, 0x0, 0x1])); -}); diff --git a/m1/JavaScript-client/src/tests/unit/hex_string.test.ts b/m1/JavaScript-client/src/tests/unit/hex_string.test.ts deleted file mode 100644 index 60b6cd48f..000000000 --- a/m1/JavaScript-client/src/tests/unit/hex_string.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { HexString } from "../../utils"; - -const withoutPrefix = "007711b4d0"; -const withPrefix = `0x${withoutPrefix}`; - -function validate(hexString: HexString) { - expect(hexString.hex()).toBe(withPrefix); - expect(hexString.toString()).toBe(withPrefix); - expect(`${hexString}`).toBe(withPrefix); - expect(hexString.noPrefix()).toBe(withoutPrefix); -} - -test("from/to Uint8Array", () => { - const hs = new HexString(withoutPrefix); - expect(HexString.fromUint8Array(hs.toUint8Array()).hex()).toBe(withPrefix); -}); - -test("accepts input without prefix", () => { - const hs = new HexString(withoutPrefix); - validate(hs); -}); - -test("accepts input with prefix", () => { - const hs = new HexString(withPrefix); - validate(hs); -}); - -test("ensures input when string", () => { - const hs = HexString.ensure(withoutPrefix); - validate(hs); -}); - -test("ensures input when HexString", () => { - const hs1 = new HexString(withPrefix); - const hs = HexString.ensure(hs1); - validate(hs); -}); - -test("short address form correct", () => { - const hs1 = new HexString(withoutPrefix); - expect(hs1.toShortString()).toBe("0x7711b4d0"); - const hs2 = new HexString("0x2185b82cef9bc46249ff2dbc56c265f6a0e3bdb7b9498cc45e4f6e429530fdc0"); - expect(hs2.toShortString()).toBe("0x2185b82cef9bc46249ff2dbc56c265f6a0e3bdb7b9498cc45e4f6e429530fdc0"); -}); diff --git a/m1/JavaScript-client/src/tests/unit/misc.test.ts b/m1/JavaScript-client/src/tests/unit/misc.test.ts deleted file mode 100644 index 958f940e1..000000000 --- a/m1/JavaScript-client/src/tests/unit/misc.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { AptosClient } from "../../providers/aptos_client"; - -test("test fixNodeUrl", () => { - expect(new AptosClient("https://test.com").client.request.config.BASE).toBe("https://test.com/v1"); - expect(new AptosClient("https://test.com/").client.request.config.BASE).toBe("https://test.com/v1"); - expect(new AptosClient("https://test.com/v1").client.request.config.BASE).toBe("https://test.com/v1"); - expect(new AptosClient("https://test.com/v1/").client.request.config.BASE).toBe("https://test.com/v1"); - expect(new AptosClient("https://test.com", {}, true).client.request.config.BASE).toBe("https://test.com"); -}); diff --git a/m1/JavaScript-client/src/tests/unit/multi_ed25519.test.ts b/m1/JavaScript-client/src/tests/unit/multi_ed25519.test.ts deleted file mode 100644 index 7e489c47a..000000000 --- a/m1/JavaScript-client/src/tests/unit/multi_ed25519.test.ts +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable max-len */ -import { HexString } from "../../utils"; -import { bcsToBytes, Deserializer } from "../../bcs"; -import { Ed25519PublicKey, Ed25519Signature } from "../../aptos_types/ed25519"; -import { MultiEd25519PublicKey, MultiEd25519Signature } from "../../aptos_types/multi_ed25519"; - -describe("MultiEd25519", () => { - it("public key serializes to bytes correctly", async () => { - const publicKey1 = "b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200"; - const publicKey2 = "aef3f4a4b8eca1dfc343361bf8e436bd42de9259c04b8314eb8e2054dd6e82ab"; - const publicKey3 = "8a5762e21ac1cdb3870442c77b4c3af58c7cedb8779d0270e6d4f1e2f7367d74"; - - const pubKeyMultiSig = new MultiEd25519PublicKey( - [ - new Ed25519PublicKey(new HexString(publicKey1).toUint8Array()), - new Ed25519PublicKey(new HexString(publicKey2).toUint8Array()), - new Ed25519PublicKey(new HexString(publicKey3).toUint8Array()), - ], - 2, - ); - - expect(HexString.fromUint8Array(pubKeyMultiSig.toBytes()).noPrefix()).toEqual( - "b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200aef3f4a4b8eca1dfc343361bf8e436bd42de9259c04b8314eb8e2054dd6e82ab8a5762e21ac1cdb3870442c77b4c3af58c7cedb8779d0270e6d4f1e2f7367d7402", - ); - }); - - it("public key deserializes from bytes correctly", async () => { - const publicKey1 = "b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200"; - const publicKey2 = "aef3f4a4b8eca1dfc343361bf8e436bd42de9259c04b8314eb8e2054dd6e82ab"; - const publicKey3 = "8a5762e21ac1cdb3870442c77b4c3af58c7cedb8779d0270e6d4f1e2f7367d74"; - - const pubKeyMultiSig = new MultiEd25519PublicKey( - [ - new Ed25519PublicKey(new HexString(publicKey1).toUint8Array()), - new Ed25519PublicKey(new HexString(publicKey2).toUint8Array()), - new Ed25519PublicKey(new HexString(publicKey3).toUint8Array()), - ], - 2, - ); - const deserialzed = MultiEd25519PublicKey.deserialize(new Deserializer(bcsToBytes(pubKeyMultiSig))); - expect(HexString.fromUint8Array(deserialzed.toBytes()).noPrefix()).toEqual( - HexString.fromUint8Array(pubKeyMultiSig.toBytes()).noPrefix(), - ); - }); - - it("signature serializes to bytes correctly", async () => { - // eslint-disable-next-line operator-linebreak - const sig1 = - "e6f3ba05469b2388492397840183945d4291f0dd3989150de3248e06b4cefe0ddf6180a80a0f04c045ee8f362870cb46918478cd9b56c66076f94f3efd5a8805"; - // eslint-disable-next-line operator-linebreak - const sig2 = - "2ae0818b7e51b853f1e43dc4c89a1f5fabc9cb256030a908f9872f3eaeb048fb1e2b4ffd5a9d5d1caedd0c8b7d6155ed8071e913536fa5c5a64327b6f2d9a102"; - const bitmap = "c0000000"; - - const multisig = new MultiEd25519Signature( - [ - new Ed25519Signature(new HexString(sig1).toUint8Array()), - new Ed25519Signature(new HexString(sig2).toUint8Array()), - ], - new HexString(bitmap).toUint8Array(), - ); - - expect(HexString.fromUint8Array(multisig.toBytes()).noPrefix()).toEqual( - "e6f3ba05469b2388492397840183945d4291f0dd3989150de3248e06b4cefe0ddf6180a80a0f04c045ee8f362870cb46918478cd9b56c66076f94f3efd5a88052ae0818b7e51b853f1e43dc4c89a1f5fabc9cb256030a908f9872f3eaeb048fb1e2b4ffd5a9d5d1caedd0c8b7d6155ed8071e913536fa5c5a64327b6f2d9a102c0000000", - ); - }); - - it("signature deserializes from bytes correctly", async () => { - // eslint-disable-next-line operator-linebreak - const sig1 = - "e6f3ba05469b2388492397840183945d4291f0dd3989150de3248e06b4cefe0ddf6180a80a0f04c045ee8f362870cb46918478cd9b56c66076f94f3efd5a8805"; - // eslint-disable-next-line operator-linebreak - const sig2 = - "2ae0818b7e51b853f1e43dc4c89a1f5fabc9cb256030a908f9872f3eaeb048fb1e2b4ffd5a9d5d1caedd0c8b7d6155ed8071e913536fa5c5a64327b6f2d9a102"; - const bitmap = "c0000000"; - - const multisig = new MultiEd25519Signature( - [ - new Ed25519Signature(new HexString(sig1).toUint8Array()), - new Ed25519Signature(new HexString(sig2).toUint8Array()), - ], - new HexString(bitmap).toUint8Array(), - ); - - const deserialzed = MultiEd25519Signature.deserialize(new Deserializer(bcsToBytes(multisig))); - expect(HexString.fromUint8Array(deserialzed.toBytes()).noPrefix()).toEqual( - HexString.fromUint8Array(multisig.toBytes()).noPrefix(), - ); - }); - - it("creates a valid bitmap", () => { - expect(MultiEd25519Signature.createBitmap([0, 2, 31])).toEqual( - new Uint8Array([0b10100000, 0b00000000, 0b00000000, 0b00000001]), - ); - }); - - it("throws exception when creating a bitmap with wrong bits", async () => { - expect(() => { - MultiEd25519Signature.createBitmap([32]); - }).toThrow("Invalid bit value 32."); - }); - - it("throws exception when creating a bitmap with duplicate bits", async () => { - expect(() => { - MultiEd25519Signature.createBitmap([2, 2]); - }).toThrow("Duplicated bits detected."); - }); -}); diff --git a/m1/JavaScript-client/src/tests/unit/property_map_serde.test.ts b/m1/JavaScript-client/src/tests/unit/property_map_serde.test.ts deleted file mode 100644 index ae64deb3c..000000000 --- a/m1/JavaScript-client/src/tests/unit/property_map_serde.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { deserializeValueBasedOnTypeTag, getPropertyType, getPropertyValueRaw } from "../../utils/property_map_serde"; -import { - bcsSerializeBool, - bcsSerializeStr, - bcsSerializeU128, - bcsSerializeU8, - bcsSerializeUint64, - bcsToBytes, - Bytes, -} from "../../bcs"; -import { AccountAddress } from "../../aptos_types"; -import { HexString } from "../../utils"; - -test("test property_map_serializer", () => { - function isSame(array1: Bytes, array2: Bytes): boolean { - return array1.length === array2.length && array1.every((element, index) => element === array2[index]); - } - const values = [ - "false", - "10", - "18446744073709551615", - "340282366920938463463374607431768211455", - "hello", - "0x1", - "I am a string", - ]; - const types = ["bool", "u8", "u64", "u128", "0x1::string::String", "address", "string"]; - const newValues = getPropertyValueRaw(values, types); - expect(isSame(newValues[0], bcsSerializeBool(false))).toBe(true); - expect(isSame(newValues[1], bcsSerializeU8(10))).toBe(true); - expect(isSame(newValues[2], bcsSerializeUint64(18446744073709551615n))).toBe(true); - expect(isSame(newValues[3], bcsSerializeU128(340282366920938463463374607431768211455n))).toBe(true); - expect(isSame(newValues[4], bcsSerializeStr(values[4]))).toBe(true); - expect(isSame(newValues[5], bcsToBytes(AccountAddress.fromHex(new HexString("0x1"))))).toBe(true); -}); - -test("test propertymap deserializer", () => { - function toHexString(data: Bytes): string { - return HexString.fromUint8Array(data).hex(); - } - const values = [ - "false", - "10", - "18446744073709551615", - "340282366920938463463374607431768211455", - "hello", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "I am a string", - ]; - const types = ["bool", "u8", "u64", "u128", "0x1::string::String", "address", "string"]; - const newValues = getPropertyValueRaw(values, types); - for (let i = 0; i < values.length; i += 1) { - expect(deserializeValueBasedOnTypeTag(getPropertyType(types[i]), toHexString(newValues[i]))).toBe(values[i]); - } -}); diff --git a/m1/JavaScript-client/src/tests/unit/serializer.test.ts b/m1/JavaScript-client/src/tests/unit/serializer.test.ts deleted file mode 100644 index 4d6942a3f..000000000 --- a/m1/JavaScript-client/src/tests/unit/serializer.test.ts +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { Serializer } from "../../bcs/serializer"; - -describe("BCS Serializer", () => { - let serializer: Serializer; - - beforeEach(() => { - serializer = new Serializer(); - }); - - it("serializes a non-empty string", () => { - serializer.serializeStr("çå∞≠¢õß∂ƒ∫"); - expect(serializer.getBytes()).toEqual( - new Uint8Array([ - 24, 0xc3, 0xa7, 0xc3, 0xa5, 0xe2, 0x88, 0x9e, 0xe2, 0x89, 0xa0, 0xc2, 0xa2, 0xc3, 0xb5, 0xc3, 0x9f, 0xe2, 0x88, - 0x82, 0xc6, 0x92, 0xe2, 0x88, 0xab, - ]), - ); - }); - - it("serializes an empty string", () => { - serializer.serializeStr(""); - expect(serializer.getBytes()).toEqual(new Uint8Array([0])); - }); - - it("serializes dynamic length bytes", () => { - serializer.serializeBytes(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73])); - expect(serializer.getBytes()).toEqual(new Uint8Array([5, 0x41, 0x70, 0x74, 0x6f, 0x73])); - }); - - it("serializes dynamic length bytes with zero elements", () => { - serializer.serializeBytes(new Uint8Array([])); - expect(serializer.getBytes()).toEqual(new Uint8Array([0])); - }); - - it("serializes fixed length bytes", () => { - serializer.serializeFixedBytes(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73])); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x41, 0x70, 0x74, 0x6f, 0x73])); - }); - - it("serializes fixed length bytes with zero element", () => { - serializer.serializeFixedBytes(new Uint8Array([])); - expect(serializer.getBytes()).toEqual(new Uint8Array([])); - }); - - it("serializes a boolean value", () => { - serializer.serializeBool(true); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x01])); - - serializer = new Serializer(); - serializer.serializeBool(false); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x00])); - }); - - it("throws when serializing a boolean value with wrong data type", () => { - expect(() => { - // @ts-ignore - serializer.serializeBool(12); - }).toThrow("Value needs to be a boolean"); - }); - - it("serializes a uint8", () => { - serializer.serializeU8(255); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xff])); - }); - - it("throws when serializing uint8 with out of range value", () => { - expect(() => { - serializer.serializeU8(256); - }).toThrow("Value is out of range"); - - expect(() => { - serializer = new Serializer(); - serializer.serializeU8(-1); - }).toThrow("Value is out of range"); - }); - - it("serializes a uint16", () => { - serializer.serializeU16(65535); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xff, 0xff])); - - serializer = new Serializer(); - serializer.serializeU16(4660); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x34, 0x12])); - }); - - it("throws when serializing uint16 with out of range value", () => { - expect(() => { - serializer.serializeU16(65536); - }).toThrow("Value is out of range"); - - expect(() => { - serializer = new Serializer(); - serializer.serializeU16(-1); - }).toThrow("Value is out of range"); - }); - - it("serializes a uint32", () => { - serializer.serializeU32(4294967295); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xff, 0xff, 0xff, 0xff])); - - serializer = new Serializer(); - serializer.serializeU32(305419896); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x78, 0x56, 0x34, 0x12])); - }); - - it("throws when serializing uint32 with out of range value", () => { - expect(() => { - serializer.serializeU32(4294967296); - }).toThrow("Value is out of range"); - - expect(() => { - serializer = new Serializer(); - serializer.serializeU32(-1); - }).toThrow("Value is out of range"); - }); - - it("serializes a uint64", () => { - serializer.serializeU64(BigInt("18446744073709551615")); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])); - - serializer = new Serializer(); - serializer.serializeU64(BigInt("1311768467750121216")); - expect(serializer.getBytes()).toEqual(new Uint8Array([0x00, 0xef, 0xcd, 0xab, 0x78, 0x56, 0x34, 0x12])); - }); - - it("throws when serializing uint64 with out of range value", () => { - expect(() => { - serializer.serializeU64(BigInt("18446744073709551616")); - }).toThrow("Value is out of range"); - - expect(() => { - serializer = new Serializer(); - serializer.serializeU64(-1); - }).toThrow("Value is out of range"); - }); - - it("serializes a uint128", () => { - serializer.serializeU128(BigInt("340282366920938463463374607431768211455")); - expect(serializer.getBytes()).toEqual( - new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), - ); - - serializer = new Serializer(); - serializer.serializeU128(BigInt("1311768467750121216")); - expect(serializer.getBytes()).toEqual( - new Uint8Array([0x00, 0xef, 0xcd, 0xab, 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), - ); - }); - - it("throws when serializing uint128 with out of range value", () => { - expect(() => { - serializer.serializeU128(BigInt("340282366920938463463374607431768211456")); - }).toThrow("Value is out of range"); - - expect(() => { - serializer = new Serializer(); - serializer.serializeU128(-1); - }).toThrow("Value is out of range"); - }); - - it("serializes a uleb128", () => { - serializer.serializeU32AsUleb128(104543565); - expect(serializer.getBytes()).toEqual(new Uint8Array([0xcd, 0xea, 0xec, 0x31])); - }); - - it("throws when serializing uleb128 with out of range value", () => { - expect(() => { - serializer.serializeU32AsUleb128(4294967296); - }).toThrow("Value is out of range"); - - expect(() => { - serializer = new Serializer(); - serializer.serializeU32AsUleb128(-1); - }).toThrow("Value is out of range"); - }); -}); diff --git a/m1/JavaScript-client/src/tests/unit/test_helper.test.ts b/m1/JavaScript-client/src/tests/unit/test_helper.test.ts deleted file mode 100644 index 679e1d77f..000000000 --- a/m1/JavaScript-client/src/tests/unit/test_helper.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { FaucetClient } from "../../plugins/faucet_client"; -import { OpenAPIConfig } from "../../generated"; -import { CustomEndpoints } from "../../utils/api-endpoints"; - -export const NODE_URL = process.env.APTOS_NODE_URL!; -export const FAUCET_URL = process.env.APTOS_FAUCET_URL!; -export const API_TOKEN = process.env.API_TOKEN!; -export const FAUCET_AUTH_TOKEN = process.env.FAUCET_AUTH_TOKEN!; -export const PROVIDER_LOCAL_NETWORK_CONFIG: CustomEndpoints = { fullnodeUrl: NODE_URL, indexerUrl: NODE_URL }; - -// account to use for ANS tests, this account matches the one in sdk-release.yaml -export const ANS_OWNER_ADDRESS = "0x585fc9f0f0c54183b039ffc770ca282ebd87307916c215a3e692f2f8e4305e82"; -export const ANS_OWNER_PK = "0x37368b46ce665362562c6d1d4ec01a08c8644c488690df5a17e13ba163e20221"; - -/** - * Returns an instance of a FaucetClient with NODE_URL and FAUCET_URL from the - * environment. If the FAUCET_AUTH_TOKEN environment variable is set, it will - * pass that along in the header in the format the faucet expects. - */ -export function getFaucetClient(): FaucetClient { - const config: Partial = {}; - if (process.env.FAUCET_AUTH_TOKEN) { - config.HEADERS = { Authorization: `Bearer ${process.env.FAUCET_AUTH_TOKEN}` }; - } - return new FaucetClient(NODE_URL, FAUCET_URL, config); -} - -test("noop", () => { - // All TS files are compiled by default into the npm package - // Adding this empty test allows us to: - // 1. Guarantee that this test library won't get compiled - // 2. Prevent jest from exploding when it finds a file with no tests in it -}); - -export const longTestTimeout = 120 * 1000; diff --git a/m1/JavaScript-client/src/tests/unit/transaction_builder.test.ts b/m1/JavaScript-client/src/tests/unit/transaction_builder.test.ts deleted file mode 100644 index a154638de..000000000 --- a/m1/JavaScript-client/src/tests/unit/transaction_builder.test.ts +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/* eslint-disable max-len */ -import nacl from "tweetnacl"; -import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; -import { bcsSerializeBool, bcsSerializeUint64, bcsToBytes, Bytes } from "../../bcs"; -import { HexString } from "../../utils"; - -import { TransactionBuilderEd25519, TransactionBuilder } from "../../transaction_builder/index"; -import { - ChainId, - Ed25519Signature, - RawTransaction, - Script, - EntryFunction, - StructTag, - TransactionArgumentAddress, - TransactionArgumentU8, - TransactionArgumentU8Vector, - TransactionPayloadScript, - TransactionPayloadEntryFunction, - TypeTagStruct, - TransactionArgumentU16, - TransactionArgumentU32, - TransactionArgumentU256, - AccountAddress, - TypeTagBool, -} from "../../aptos_types"; - -const ADDRESS_1 = "0x1222"; -const ADDRESS_2 = "0xdd"; -const ADDRESS_3 = "0x0a550c18"; -const ADDRESS_4 = "0x01"; -const PRIVATE_KEY = "9bf49a6a0755f953811fce125f2683d50429c3bb49e074147e0089a52eae155f"; -const TXN_EXPIRE = "18446744073709551615"; - -function hexSignedTxn(signedTxn: Uint8Array): string { - return bytesToHex(signedTxn); -} - -function sign(rawTxn: RawTransaction): Bytes { - const privateKeyBytes = new HexString(PRIVATE_KEY).toUint8Array(); - const signingKey = nacl.sign.keyPair.fromSeed(privateKeyBytes.slice(0, 32)); - const { publicKey } = signingKey; - - const txnBuilder = new TransactionBuilderEd25519( - (signingMessage) => new Ed25519Signature(nacl.sign(signingMessage, signingKey.secretKey).slice(0, 64)), - publicKey, - ); - - return txnBuilder.sign(rawTxn); -} - -test("throws when preparing signing message with invalid payload", () => { - expect(() => { - // @ts-ignore - TransactionBuilder.getSigningMessage("invalid"); - }).toThrow("Unknown transaction type."); -}); - -test("serialize entry function payload with no type args", () => { - const entryFunctionPayload = new TransactionPayloadEntryFunction( - EntryFunction.natural( - `${ADDRESS_1}::aptos_coin`, - "transfer", - [], - [bcsToBytes(AccountAddress.fromHex(ADDRESS_2)), bcsSerializeUint64(1)], - ), - ); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(new HexString(ADDRESS_3)), - BigInt(0), - entryFunctionPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c1800000000000000000200000000000000000000000000000000000000000000000000000000000012220a6170746f735f636f696e087472616e7366657200022000000000000000000000000000000000000000000000000000000000000000dd080100000000000000d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200409c570996380897f38b8d7008d726fb45d6ded0689216e56b73f523492cba92deb6671c27e9a44d2a6fdfdb497420d00c621297a23d6d0298895e0d58cff6060c", - ); -}); - -test("serialize entry function payload with type args", () => { - const token = new TypeTagStruct(StructTag.fromString(`${ADDRESS_4}::aptos_coin::AptosCoin`)); - - const entryFunctionPayload = new TransactionPayloadEntryFunction( - EntryFunction.natural( - `${ADDRESS_1}::coin`, - "transfer", - [token], - [bcsToBytes(AccountAddress.fromHex(ADDRESS_2)), bcsSerializeUint64(1)], - ), - ); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - entryFunctionPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c18000000000000000002000000000000000000000000000000000000000000000000000000000000122204636f696e087472616e73666572010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e00022000000000000000000000000000000000000000000000000000000000000000dd080100000000000000d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a4920040112162f543ca92b4f14c1b09b7f52894a127f5428b0d407c09c8efb3a136cff50e550aea7da1226f02571d79230b80bd79096ea0d796789ad594b8fbde695404", - ); -}); - -test("serialize entry function payload with type args but no function args", () => { - const token = new TypeTagStruct(StructTag.fromString(`${ADDRESS_4}::aptos_coin::AptosCoin`)); - - const entryFunctionPayload = new TransactionPayloadEntryFunction( - EntryFunction.natural(`${ADDRESS_1}::coin`, "fake_func", [token], []), - ); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - entryFunctionPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c18000000000000000002000000000000000000000000000000000000000000000000000000000000122204636f696e0966616b655f66756e63010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e0000d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200400e2d1cc4a27893cbae36d8b6a7150977c7620e065f359840413c5478a25f20a383250a9cdcb4fd71f7d171856f38972da30a9d10072e164614d96379004aa500", - ); -}); - -test("serialize entry function payload with generic type args and function args", () => { - const token = new TypeTagStruct(StructTag.fromString(`0x14::token::Token`)); - - const entryFunctionPayload = new TransactionPayloadEntryFunction( - EntryFunction.natural( - `${ADDRESS_1}::aptos_token`, - "fake_typed_func", - [token, new TypeTagBool()], - [bcsToBytes(AccountAddress.fromHex(ADDRESS_2)), bcsSerializeBool(true)], - ), - ); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - entryFunctionPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c1800000000000000000200000000000000000000000000000000000000000000000000000000000012220b6170746f735f746f6b656e0f66616b655f74797065645f66756e630207000000000000000000000000000000000000000000000000000000000000001405746f6b656e05546f6b656e0000022000000000000000000000000000000000000000000000000000000000000000dd0101d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a4920040367085186aeef58a0256fc64ecb86b88a86f8a8e42151e0e9aae1ab6d426c4968f2cab664261ea6bb868869154fe6e946c082774741d5143e57a1d802fd1b700", - ); -}); - -test("serialize script payload with no type args and no function args", () => { - const script = hexToBytes("a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102"); - - const scriptPayload = new TransactionPayloadScript(new Script(script, [], [])); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - scriptPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c1800000000000000000026a11ceb0b030000000105000100000000050601000000000000000600000000000000001a01020000d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a4920040266935990105df40f3a82a3f41ad9ceb4b79451495403dd976191382bb07f8c9b401702968a64b5176762e62036f75c6fc2b770a0988716e41d469fff2349a08", - ); -}); - -test("serialize script payload with type args but no function args", () => { - const token = new TypeTagStruct(StructTag.fromString(`${ADDRESS_4}::aptos_coin::AptosCoin`)); - - const script = hexToBytes("a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102"); - - const scriptPayload = new TransactionPayloadScript(new Script(script, [token], [])); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - scriptPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c1800000000000000000026a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e0000d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a4920040bd241a6f31dfdfca0031ca5874fbf81800b5f632642321a11c41b4fead4b41d808617e91dd655fde7e9f263127f07bb5d56c7c925fe797728dcc9b55be120604", - ); -}); - -test("serialize script payload with type arg and function arg", () => { - const token = new TypeTagStruct(StructTag.fromString(`${ADDRESS_4}::aptos_coin::AptosCoin`)); - - const argU8 = new TransactionArgumentU8(2); - - const script = hexToBytes("a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102"); - - const scriptPayload = new TransactionPayloadScript(new Script(script, [token], [argU8])); - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - scriptPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c1800000000000000000026a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e00010002d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200409936b8d22cec685e720761f6c6135e020911f1a26e220e2a0f3317f5a68942531987259ac9e8688158c77df3e7136637056047d9524edad88ee45d61a9346602", - ); -}); - -test("serialize script payload with one type arg and two function args", () => { - const token = new TypeTagStruct(StructTag.fromString(`${ADDRESS_4}::aptos_coin::AptosCoin`)); - - const argU8Vec = new TransactionArgumentU8Vector(bcsSerializeUint64(1)); - const argAddress = new TransactionArgumentAddress(AccountAddress.fromHex("0x01")); - - const script = hexToBytes("a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102"); - - const scriptPayload = new TransactionPayloadScript(new Script(script, [token], [argU8Vec, argAddress])); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - scriptPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c1800000000000000000026a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e000204080100000000000000030000000000000000000000000000000000000000000000000000000000000001d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a492004055c7499795ea68d7acfa64a58f19efa2ba3b977fa58ae93ae8c0732c0f6d6dd084d92bbe4edc2a0d687031cae90da117abfac16ebd902e764bdc38a2154a2102", - ); -}); - -test("serialize script payload with new integer types (u16, u32, u256) as args", () => { - const argU16 = new TransactionArgumentU16(0xf111); - const argU32 = new TransactionArgumentU32(0xf1111111); - const argU256 = new TransactionArgumentU256( - BigInt("0xf111111111111111111111111111111111111111111111111111111111111111"), - ); - - const script = hexToBytes(""); - - const scriptPayload = new TransactionPayloadScript(new Script(script, [], [argU16, argU32, argU256])); - - const rawTxn = new RawTransaction( - AccountAddress.fromHex(ADDRESS_3), - BigInt(0), - scriptPayload, - BigInt(2000), - BigInt(0), - BigInt(TXN_EXPIRE), - new ChainId(4), - ); - - const signedTxn = sign(rawTxn); - - expect(hexSignedTxn(signedTxn)).toBe( - "000000000000000000000000000000000000000000000000000000000a550c180000000000000000000000030611f107111111f10811111111111111111111111111111111111111111111111111111111111111f1d0070000000000000000000000000000ffffffffffffffff040020b9c6ee1630ef3e711144a648db06bbb2284f7274cfbee53ffcee503cc1a49200409402b773f66cf5444efe4de38a026cf9b34e0327798ea01f0695db8e8e0888e20387b08f504b620dcffbc382e3ac141c0ec9a820c5f58b5da2eec589a9e86b0b", - ); -}); diff --git a/m1/JavaScript-client/src/tests/unit/transaction_vector.test.ts b/m1/JavaScript-client/src/tests/unit/transaction_vector.test.ts deleted file mode 100644 index 861fbaf0c..000000000 --- a/m1/JavaScript-client/src/tests/unit/transaction_vector.test.ts +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -/** - * Do fuzzing tests with test vectors. The test vectors are produced by the same code - * used by the Aptos Blockchain. The test vectors are arrays of JSON objects. - * Each JSON object contains randomized inputs to Transaction Builder and BCS and - * the expected outputs. - */ - -import path from "path"; -import nacl from "tweetnacl"; -import fs from "fs"; -import { bytesToHex } from "@noble/hashes/utils"; -import { - AccountAddress, - ChainId, - RawTransaction, - EntryFunction, - StructTag, - TypeTag, - TypeTagVector, - TransactionPayloadEntryFunction, - Identifier, - TypeTagStruct, - TypeTagAddress, - TypeTagBool, - TypeTagU8, - TypeTagU64, - TypeTagU128, - TypeTagSigner, - Ed25519Signature, - TransactionPayloadScript, - Script, - TransactionArgument, - TransactionArgumentBool, - TransactionArgumentU8, - TransactionArgumentU64, - TransactionArgumentAddress, - TransactionArgumentU8Vector, - TransactionArgumentU128, -} from "../../aptos_types"; -import { HexString } from "../../utils"; -import { TransactionBuilderEd25519 } from "../../transaction_builder/builder"; - -// eslint-disable-next-line operator-linebreak -const VECTOR_FILES_ROOT_DIR = - process.env.VECTOR_FILES_ROOT_DIR || path.resolve(__dirname, "..", "..", "..", "..", "..", "..", "api", "goldens"); - -const ENTRY_FUNCTION_VECTOR = path.join( - VECTOR_FILES_ROOT_DIR, - "aptos_api__tests__transaction_vector_test__test_entry_function_payload.json", -); - -const SCRIPT_VECTOR = path.join( - VECTOR_FILES_ROOT_DIR, - "aptos_api__tests__transaction_vector_test__test_script_payload.json", -); - -function parseTypeTag(typeTag: any): TypeTag { - if (typeTag.vector) { - return new TypeTagVector(parseTypeTag(typeTag.vector)); - } - - if (typeTag.struct) { - const { - address, - module, - name, - // eslint-disable-next-line @typescript-eslint/naming-convention - type_args, - }: { - address: string; - module: string; - name: string; - type_args: any[]; - } = typeTag.struct; - - const typeArgs = type_args.map((arg) => parseTypeTag(arg)); - const structTag = new StructTag( - AccountAddress.fromHex(address), - new Identifier(module), - new Identifier(name), - typeArgs, - ); - - return new TypeTagStruct(structTag); - } - - switch (typeTag) { - case "bool": - return new TypeTagBool(); - case "u8": - return new TypeTagU8(); - case "u64": - return new TypeTagU64(); - case "u128": - return new TypeTagU128(); - case "address": - return new TypeTagAddress(); - case "signer": - return new TypeTagSigner(); - default: - throw new Error("Unknown type tag"); - } -} - -function parseTransactionArgument(arg: any): TransactionArgument { - const argHasOwnProperty = (propertyName: string) => Object.prototype.hasOwnProperty.call(arg, propertyName); - if (argHasOwnProperty("U8")) { - // arg.U8 is a number - return new TransactionArgumentU8(arg.U8); - } - - if (argHasOwnProperty("U64")) { - // arg.U64 is a string literal - return new TransactionArgumentU64(BigInt(arg.U64)); - } - - if (argHasOwnProperty("U128")) { - // arg.U128 is a string literal - return new TransactionArgumentU128(BigInt(arg.U128)); - } - - if (argHasOwnProperty("Address")) { - // arg.Address is a hex string - return new TransactionArgumentAddress(AccountAddress.fromHex(arg.Address)); - } - - if (argHasOwnProperty("U8Vector")) { - // arg.U8Vector is a hex string - return new TransactionArgumentU8Vector(new HexString(arg.U8Vector).toUint8Array()); - } - - if (argHasOwnProperty("Bool")) { - return new TransactionArgumentBool(arg.Bool); - } - - throw new Error("Invalid Transaction Argument"); -} - -function sign(rawTxn: RawTransaction, privateKey: string): string { - const privateKeyBytes = new HexString(privateKey).toUint8Array(); - const signingKey = nacl.sign.keyPair.fromSeed(privateKeyBytes.slice(0, 32)); - const { publicKey } = signingKey; - - const txnBuilder = new TransactionBuilderEd25519( - (signingMessage) => new Ed25519Signature(nacl.sign(signingMessage, signingKey.secretKey).slice(0, 64)), - publicKey, - ); - - return bytesToHex(txnBuilder.sign(rawTxn)); -} - -type IRawTxn = { - // hex string for an AccountAddress - sender: string; - // u64 string literal - sequence_number: string; - // u64 string literal - max_gas_amount: string; - // u64 string literal - gas_unit_price: string; - // u64 string literal - expiration_timestamp_secs: string; - - chain_id: number; -}; - -function verify( - raw_txn: IRawTxn, - payload: TransactionPayloadEntryFunction | TransactionPayloadScript, - private_key: string, - expected_output: string, -) { - const rawTxn = new RawTransaction( - AccountAddress.fromHex(raw_txn.sender), - BigInt(raw_txn.sequence_number), - payload, - BigInt(raw_txn.max_gas_amount), - BigInt(raw_txn.gas_unit_price), - BigInt(raw_txn.expiration_timestamp_secs), - new ChainId(raw_txn.chain_id), - ); - - const signedTxn = sign(rawTxn, private_key); - - expect(signedTxn).toBe(expected_output); -} - -describe("Transaction builder vector test", () => { - it("should pass on entry function payload", () => { - const vector: any[] = JSON.parse(fs.readFileSync(ENTRY_FUNCTION_VECTOR, "utf8")); - vector.forEach(({ raw_txn, signed_txn_bcs, private_key }) => { - const payload = raw_txn.payload.EntryFunction; - const entryFunctionPayload = new TransactionPayloadEntryFunction( - EntryFunction.natural( - `${payload.module.address}::${payload.module.name}`, - payload.function, - payload.ty_args.map((tag: any) => parseTypeTag(tag)), - payload.args.map((arg: any) => new HexString(arg).toUint8Array()), - ), - ); - - verify(raw_txn, entryFunctionPayload, private_key, signed_txn_bcs); - }); - }); - - it("should pass on script payload", () => { - const vector: any[] = JSON.parse(fs.readFileSync(SCRIPT_VECTOR, "utf8")); - vector.forEach(({ raw_txn, signed_txn_bcs, private_key }) => { - const payload = raw_txn.payload.Script; - // payload.code is hex string - const code = new HexString(payload.code).toUint8Array(); - const scriptPayload = new TransactionPayloadScript( - new Script( - code, - payload.ty_args.map((tag: any) => parseTypeTag(tag)), - payload.args.map((arg: any) => parseTransactionArgument(arg)), - ), - ); - - verify(raw_txn, scriptPayload, private_key, signed_txn_bcs); - }); - }); -}); diff --git a/m1/JavaScript-client/src/tests/unit/type_tag.test.ts b/m1/JavaScript-client/src/tests/unit/type_tag.test.ts deleted file mode 100644 index 8b14a1dc8..000000000 --- a/m1/JavaScript-client/src/tests/unit/type_tag.test.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { - StructTag, - TypeTagAddress, - TypeTagBool, - TypeTagParser, - TypeTagParserError, - TypeTagStruct, -} from "../../aptos_types/type_tag"; - -const expectedTypeTag = { - string: "0x0000000000000000000000000000000000000000000000000000000000000001::some_module::SomeResource", - address: "0x0000000000000000000000000000000000000000000000000000000000000001", - module_name: "some_module", - name: "SomeResource", -}; - -describe("StructTag", () => { - test("make sure StructTag.fromString works with un-nested type tag", () => { - const structTag = StructTag.fromString(expectedTypeTag.string); - expect(structTag.address.toHexString()).toEqual(expectedTypeTag.address); - expect(structTag.module_name.value).toEqual(expectedTypeTag.module_name); - expect(structTag.name.value).toEqual(expectedTypeTag.name); - expect(structTag.type_args.length).toEqual(0); - }); - - test("make sure StructTag.fromString works with nested type tag", () => { - const structTag = StructTag.fromString( - `${expectedTypeTag.string}<${expectedTypeTag.string}, ${expectedTypeTag.string}>`, - ); - expect(structTag.address.toHexString()).toEqual(expectedTypeTag.address); - expect(structTag.module_name.value).toEqual(expectedTypeTag.module_name); - expect(structTag.name.value).toEqual(expectedTypeTag.name); - expect(structTag.type_args.length).toEqual(2); - - // make sure the nested type tag is correct - for (const typeArg of structTag.type_args) { - const nestedTypeTag = typeArg as TypeTagStruct; - expect(nestedTypeTag.value.address.toHexString()).toEqual(expectedTypeTag.address); - expect(nestedTypeTag.value.module_name.value).toEqual(expectedTypeTag.module_name); - expect(nestedTypeTag.value.name.value).toEqual(expectedTypeTag.name); - expect(nestedTypeTag.value.type_args.length).toEqual(0); - } - }); -}); - -describe("TypeTagParser", () => { - test("make sure parseTypeTag throws TypeTagParserError 'Invalid type tag' if invalid format", () => { - let typeTag = "0x000"; - let parser = new TypeTagParser(typeTag); - - try { - parser.parseTypeTag(); - } catch (error) { - expect(error).toBeInstanceOf(TypeTagParserError); - const typeTagError = error as TypeTagParserError; - expect(typeTagError.message).toEqual("Invalid type tag."); - } - - typeTag = "0x1::some_module::SomeResource<0x1>"; - parser = new TypeTagParser(typeTag); - expect(() => parser.parseTypeTag()).toThrowError("Invalid type tag."); - }); - - test("make sure parseTypeTag works with un-nested type tag", () => { - const parser = new TypeTagParser(expectedTypeTag.string); - const result = parser.parseTypeTag() as TypeTagStruct; - expect(result.value.address.toHexString()).toEqual(expectedTypeTag.address); - expect(result.value.module_name.value).toEqual(expectedTypeTag.module_name); - expect(result.value.name.value).toEqual(expectedTypeTag.name); - expect(result.value.type_args.length).toEqual(0); - }); - - test("make sure parseTypeTag works with nested type tag", () => { - const typeTag = "0x1::some_module::SomeResource<0x1::some_module::SomeResource, 0x1::some_module::SomeResource>"; - const parser = new TypeTagParser(typeTag); - const result = parser.parseTypeTag() as TypeTagStruct; - expect(result.value.address.toHexString()).toEqual(expectedTypeTag.address); - expect(result.value.module_name.value).toEqual(expectedTypeTag.module_name); - expect(result.value.name.value).toEqual(expectedTypeTag.name); - expect(result.value.type_args.length).toEqual(2); - - // make sure the nested type tag is correct - for (const typeArg of result.value.type_args) { - const nestedTypeTag = typeArg as TypeTagStruct; - expect(nestedTypeTag.value.address.toHexString()).toEqual(expectedTypeTag.address); - expect(nestedTypeTag.value.module_name.value).toEqual(expectedTypeTag.module_name); - expect(nestedTypeTag.value.name.value).toEqual(expectedTypeTag.name); - expect(nestedTypeTag.value.type_args.length).toEqual(0); - } - }); - - describe("parse Object type", () => { - test("TypeTagParser successfully parses an Object type", () => { - const typeTag = "0x1::object::Object"; - const parser = new TypeTagParser(typeTag); - const result = parser.parseTypeTag(); - expect(result instanceof TypeTagAddress).toBeTruthy(); - }); - - test("TypeTagParser successfully parses a strcut with a nested Object type", () => { - const typeTag = "0x1::some_module::SomeResource<0x1::object::Object>"; - const parser = new TypeTagParser(typeTag); - const result = parser.parseTypeTag() as TypeTagStruct; - expect(result.value.address.toHexString()).toEqual(expectedTypeTag.address); - expect(result.value.module_name.value).toEqual("some_module"); - expect(result.value.name.value).toEqual("SomeResource"); - expect(result.value.type_args[0] instanceof TypeTagAddress).toBeTruthy(); - }); - - test("TypeTagParser successfully parses a strcut with a nested Object and Struct types", () => { - const typeTag = "0x1::some_module::SomeResource<0x4::object::Object, 0x1::some_module::SomeResource>"; - const parser = new TypeTagParser(typeTag); - const result = parser.parseTypeTag() as TypeTagStruct; - expect(result.value.address.toHexString()).toEqual(expectedTypeTag.address); - expect(result.value.module_name.value).toEqual("some_module"); - expect(result.value.name.value).toEqual("SomeResource"); - expect(result.value.type_args.length).toEqual(2); - expect(result.value.type_args[0] instanceof TypeTagAddress).toBeTruthy(); - expect(result.value.type_args[1] instanceof TypeTagStruct).toBeTruthy(); - }); - }); - - describe("supports generic types", () => { - test("throws an error when the type to use is not provided", () => { - const typeTag = "T0"; - const parser = new TypeTagParser(typeTag); - expect(() => { - parser.parseTypeTag(); - }).toThrow("Can't convert generic type since no typeTags were specified."); - }); - - test("successfully parses a generic type tag to the provided type", () => { - const typeTag = "T0"; - const parser = new TypeTagParser(typeTag, ["bool"]); - const result = parser.parseTypeTag(); - expect(result instanceof TypeTagBool).toBeTruthy(); - }); - }); -}); diff --git a/m1/JavaScript-client/src/transaction_builder/builder.ts b/m1/JavaScript-client/src/transaction_builder/builder.ts deleted file mode 100644 index 62f0821a3..000000000 --- a/m1/JavaScript-client/src/transaction_builder/builder.ts +++ /dev/null @@ -1,437 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { sha3_256 as sha3Hash } from "@noble/hashes/sha3"; -import { - Ed25519PublicKey, - Ed25519Signature, - MultiEd25519PublicKey, - MultiEd25519Signature, - RawTransaction, - SignedTransaction, - TransactionAuthenticatorEd25519, - TransactionAuthenticatorMultiEd25519, - SigningMessage, - MultiAgentRawTransaction, - AccountAddress, - EntryFunction, - Identifier, - ChainId, - Script, - TransactionPayload, - TransactionArgument, - TransactionPayloadEntryFunction, - TransactionPayloadScript, - ModuleId, - TypeTagParser, -} from "../aptos_types"; -import { bcsToBytes, Bytes, Deserializer, Serializer, Uint64, Uint8 } from "../bcs"; -import { ArgumentABI, EntryFunctionABI, ScriptABI, TransactionScriptABI, TypeArgumentABI } from "../aptos_types/abi"; -import { argToTransactionArgument, serializeArg } from "./builder_utils"; -import * as Gen from "../generated/index"; -import { - DEFAULT_TXN_EXP_SEC_FROM_NOW, - DEFAULT_MAX_GAS_AMOUNT, - HexString, - MaybeHexString, - MemoizeExpiring, -} from "../utils"; - -export { TypeTagParser } from "../aptos_types"; - -const RAW_TRANSACTION_SALT = "APTOS::RawTransaction"; -const RAW_TRANSACTION_WITH_DATA_SALT = "APTOS::RawTransactionWithData"; - -type AnyRawTransaction = RawTransaction | MultiAgentRawTransaction; - -/** - * Function that takes in a Signing Message (serialized raw transaction) - * and returns a signature - */ -export type SigningFn = (txn: SigningMessage) => Ed25519Signature | MultiEd25519Signature; - -export class TransactionBuilder { - protected readonly signingFunction: F; - - constructor(signingFunction: F, public readonly rawTxnBuilder?: TransactionBuilderABI) { - this.signingFunction = signingFunction; - } - - /** - * Builds a RawTransaction. Relays the call to TransactionBuilderABI.build - * @param func - * @param ty_tags - * @param args - */ - build(func: string, ty_tags: string[], args: any[]): RawTransaction { - if (!this.rawTxnBuilder) { - throw new Error("this.rawTxnBuilder doesn't exist."); - } - - return this.rawTxnBuilder.build(func, ty_tags, args); - } - - /** Generates a Signing Message out of a raw transaction. */ - static getSigningMessage(rawTxn: AnyRawTransaction): SigningMessage { - const hash = sha3Hash.create(); - if (rawTxn instanceof RawTransaction) { - hash.update(RAW_TRANSACTION_SALT); - } else if (rawTxn instanceof MultiAgentRawTransaction) { - hash.update(RAW_TRANSACTION_WITH_DATA_SALT); - } else { - throw new Error("Unknown transaction type."); - } - - const prefix = hash.digest(); - - const body = bcsToBytes(rawTxn); - - const mergedArray = new Uint8Array(prefix.length + body.length); - mergedArray.set(prefix); - mergedArray.set(body, prefix.length); - - return mergedArray; - } -} - -/** - * Provides signing method for signing a raw transaction with single public key. - */ -export class TransactionBuilderEd25519 extends TransactionBuilder { - private readonly publicKey: Uint8Array; - - constructor(signingFunction: SigningFn, publicKey: Uint8Array, rawTxnBuilder?: TransactionBuilderABI) { - super(signingFunction, rawTxnBuilder); - this.publicKey = publicKey; - } - - rawToSigned(rawTxn: RawTransaction): SignedTransaction { - const signingMessage = TransactionBuilder.getSigningMessage(rawTxn); - const signature = this.signingFunction(signingMessage); - - const authenticator = new TransactionAuthenticatorEd25519( - new Ed25519PublicKey(this.publicKey), - signature as Ed25519Signature, - ); - - return new SignedTransaction(rawTxn, authenticator); - } - - /** Signs a raw transaction and returns a bcs serialized transaction. */ - sign(rawTxn: RawTransaction): Bytes { - return bcsToBytes(this.rawToSigned(rawTxn)); - } -} - -/** - * Provides signing method for signing a raw transaction with multisig public key. - */ -export class TransactionBuilderMultiEd25519 extends TransactionBuilder { - private readonly publicKey: MultiEd25519PublicKey; - - constructor(signingFunction: SigningFn, publicKey: MultiEd25519PublicKey) { - super(signingFunction); - this.publicKey = publicKey; - } - - rawToSigned(rawTxn: RawTransaction): SignedTransaction { - const signingMessage = TransactionBuilder.getSigningMessage(rawTxn); - const signature = this.signingFunction(signingMessage); - - const authenticator = new TransactionAuthenticatorMultiEd25519(this.publicKey, signature as MultiEd25519Signature); - - return new SignedTransaction(rawTxn, authenticator); - } - - /** Signs a raw transaction and returns a bcs serialized transaction. */ - sign(rawTxn: RawTransaction): Bytes { - return bcsToBytes(this.rawToSigned(rawTxn)); - } -} - -/** - * Config for creating raw transactions. - */ -interface ABIBuilderConfig { - sender: MaybeHexString | AccountAddress; - sequenceNumber: Uint64 | string; - gasUnitPrice: Uint64 | string; - maxGasAmount?: Uint64 | string; - expSecFromNow?: number | string; - chainId: Uint8 | string; -} - -/** - * Builds raw transactions based on ABI - */ -export class TransactionBuilderABI { - private readonly abiMap: Map; - - private readonly builderConfig: Partial; - - /** - * Constructs a TransactionBuilderABI instance - * @param abis List of binary ABIs. - * @param builderConfig Configs for creating a raw transaction. - */ - constructor(abis: Bytes[], builderConfig?: ABIBuilderConfig) { - this.abiMap = new Map(); - - abis.forEach((abi) => { - const deserializer = new Deserializer(abi); - const scriptABI = ScriptABI.deserialize(deserializer); - let k: string; - if (scriptABI instanceof EntryFunctionABI) { - const funcABI = scriptABI as EntryFunctionABI; - const { address: addr, name: moduleName } = funcABI.module_name; - k = `${HexString.fromUint8Array(addr.address).toShortString()}::${moduleName.value}::${funcABI.name}`; - } else { - const funcABI = scriptABI as TransactionScriptABI; - k = funcABI.name; - } - - if (this.abiMap.has(k)) { - throw new Error("Found conflicting ABI interfaces"); - } - - this.abiMap.set(k, scriptABI); - }); - - this.builderConfig = { - maxGasAmount: BigInt(DEFAULT_MAX_GAS_AMOUNT), - expSecFromNow: DEFAULT_TXN_EXP_SEC_FROM_NOW, - ...builderConfig, - }; - } - - private static toBCSArgs(abiArgs: any[], args: any[]): Bytes[] { - if (abiArgs.length !== args.length) { - throw new Error("Wrong number of args provided."); - } - - return args.map((arg, i) => { - const serializer = new Serializer(); - serializeArg(arg, abiArgs[i].type_tag, serializer); - return serializer.getBytes(); - }); - } - - private static toTransactionArguments(abiArgs: any[], args: any[]): TransactionArgument[] { - if (abiArgs.length !== args.length) { - throw new Error("Wrong number of args provided."); - } - - return args.map((arg, i) => argToTransactionArgument(arg, abiArgs[i].type_tag)); - } - - setSequenceNumber(seqNumber: Uint64 | string) { - this.builderConfig.sequenceNumber = BigInt(seqNumber); - } - - /** - * Builds a TransactionPayload. For dApps, chain ID and account sequence numbers are only known to the wallet. - * Instead of building a RawTransaction (requires chainID and sequenceNumber), dApps can build a TransactionPayload - * and pass the payload to the wallet for signing and sending. - * @param func Fully qualified func names, e.g. 0x1::Coin::transfer - * @param ty_tags TypeTag strings - * @param args Function arguments - * @returns TransactionPayload - */ - buildTransactionPayload(func: string, ty_tags: string[], args: any[]): TransactionPayload { - const typeTags = ty_tags.map((ty_arg) => new TypeTagParser(ty_arg).parseTypeTag()); - - let payload: TransactionPayload; - - if (!this.abiMap.has(func)) { - throw new Error(`Cannot find function: ${func}`); - } - - const scriptABI = this.abiMap.get(func); - - if (scriptABI instanceof EntryFunctionABI) { - const funcABI = scriptABI as EntryFunctionABI; - const bcsArgs = TransactionBuilderABI.toBCSArgs(funcABI.args, args); - payload = new TransactionPayloadEntryFunction( - new EntryFunction(funcABI.module_name, new Identifier(funcABI.name), typeTags, bcsArgs), - ); - } else if (scriptABI instanceof TransactionScriptABI) { - const funcABI = scriptABI as TransactionScriptABI; - const scriptArgs = TransactionBuilderABI.toTransactionArguments(funcABI.args, args); - - payload = new TransactionPayloadScript(new Script(funcABI.code, typeTags, scriptArgs)); - } else { - /* istanbul ignore next */ - throw new Error("Unknown ABI format."); - } - - return payload; - } - - /** - * Builds a RawTransaction - * @param func Fully qualified func names, e.g. 0x1::Coin::transfer - * @param ty_tags TypeTag strings. - * @example Below are valid value examples - * ``` - * // Structs are in format `AccountAddress::ModuleName::StructName` - * 0x1::aptos_coin::AptosCoin - * // Vectors are in format `vector` - * vector<0x1::aptos_coin::AptosCoin> - * bool - * u8 - * u16 - * u32 - * u64 - * u128 - * u256 - * address - * ``` - * @param args Function arguments - * @returns RawTransaction - */ - build(func: string, ty_tags: string[], args: any[]): RawTransaction { - const { sender, sequenceNumber, gasUnitPrice, maxGasAmount, expSecFromNow, chainId } = this.builderConfig; - - if (!gasUnitPrice) { - throw new Error("No gasUnitPrice provided."); - } - - const senderAccount = sender instanceof AccountAddress ? sender : AccountAddress.fromHex(sender!); - const expTimestampSec = BigInt(Math.floor(Date.now() / 1000) + Number(expSecFromNow)); - const payload = this.buildTransactionPayload(func, ty_tags, args); - - if (payload) { - return new RawTransaction( - senderAccount, - BigInt(sequenceNumber!), - payload, - BigInt(maxGasAmount!), - BigInt(gasUnitPrice!), - expTimestampSec, - new ChainId(Number(chainId)), - ); - } - - throw new Error("Invalid ABI."); - } -} - -export type RemoteABIBuilderConfig = Partial> & { - sender: MaybeHexString | AccountAddress; -}; - -interface AptosClientInterface { - getAccountModules: (accountAddress: MaybeHexString) => Promise; - getAccount: (accountAddress: MaybeHexString) => Promise; - getChainId: () => Promise; - estimateGasPrice: () => Promise; -} - -/** - * This transaction builder downloads JSON ABIs from the fullnodes. - * It then translates the JSON ABIs to the format that is accepted by TransactionBuilderABI - */ -export class TransactionBuilderRemoteABI { - // We don't want the builder to depend on the actual AptosClient. There might be circular dependencies. - constructor( - private readonly aptosClient: AptosClientInterface, - private readonly builderConfig: RemoteABIBuilderConfig, - ) {} - - // Cache for 10 minutes - @MemoizeExpiring(10 * 60 * 1000) - async fetchABI(addr: string) { - const modules = await this.aptosClient.getAccountModules(addr); - const abis = modules - .map((module) => module.abi) - .flatMap((abi) => - abi!.exposed_functions - .filter((ef) => ef.is_entry) - .map( - (ef) => - ({ - fullName: `${abi!.address}::${abi!.name}::${ef.name}`, - ...ef, - } as Gen.MoveFunction & { fullName: string }), - ), - ); - - const abiMap = new Map(); - abis.forEach((abi) => { - abiMap.set(abi.fullName, abi); - }); - - return abiMap; - } - - /** - * Builds a raw transaction. Only support script function a.k.a entry function payloads - * - * @param func fully qualified function name in format
::::, e.g. 0x1::coins::transfer - * @param ty_tags - * @param args - * @returns RawTransaction - */ - async build(func: Gen.EntryFunctionId, ty_tags: Gen.MoveType[], args: any[]): Promise { - /* eslint no-param-reassign: ["off"] */ - const normlize = (s: string) => s.replace(/^0[xX]0*/g, "0x"); - func = normlize(func); - const funcNameParts = func.split("::"); - if (funcNameParts.length !== 3) { - throw new Error( - // eslint-disable-next-line max-len - "'func' needs to be a fully qualified function name in format
::::, e.g. 0x1::coins::transfer", - ); - } - - const [addr, module] = func.split("::"); - - // Downloads the JSON abi - const abiMap = await this.fetchABI(addr); - if (!abiMap.has(func)) { - throw new Error(`${func} doesn't exist.`); - } - - const funcAbi = abiMap.get(func); - - // Remove all `signer` and `&signer` from argument list because the Move VM injects those arguments. Clients do not - // need to care about those args. `signer` and `&signer` are required be in the front of the argument list. But we - // just loop through all arguments and filter out `signer` and `&signer`. - const abiArgs = funcAbi!.params.filter((param) => param !== "signer" && param !== "&signer"); - - // Convert abi string arguments to TypeArgumentABI - const typeArgABIs = abiArgs.map( - (abiArg, i) => new ArgumentABI(`var${i}`, new TypeTagParser(abiArg, ty_tags).parseTypeTag()), - ); - - const entryFunctionABI = new EntryFunctionABI( - funcAbi!.name, - ModuleId.fromStr(`${addr}::${module}`), - "", // Doc string - funcAbi!.generic_type_params.map((_, i) => new TypeArgumentABI(`${i}`)), - typeArgABIs, - ); - - const { sender, ...rest } = this.builderConfig; - - const senderAddress = sender instanceof AccountAddress ? HexString.fromUint8Array(sender.address) : sender; - - const [{ sequence_number: sequenceNumber }, chainId, { gas_estimate: gasUnitPrice }] = await Promise.all([ - rest?.sequenceNumber - ? Promise.resolve({ sequence_number: rest?.sequenceNumber }) - : this.aptosClient.getAccount(senderAddress), - rest?.chainId ? Promise.resolve(rest?.chainId) : this.aptosClient.getChainId(), - rest?.gasUnitPrice ? Promise.resolve({ gas_estimate: rest?.gasUnitPrice }) : this.aptosClient.estimateGasPrice(), - ]); - - const builderABI = new TransactionBuilderABI([bcsToBytes(entryFunctionABI)], { - sender, - sequenceNumber, - chainId, - gasUnitPrice: BigInt(gasUnitPrice), - ...rest, - }); - - return builderABI.build(func, ty_tags, args); - } -} diff --git a/m1/JavaScript-client/src/transaction_builder/builder_utils.ts b/m1/JavaScript-client/src/transaction_builder/builder_utils.ts deleted file mode 100644 index c8d6c2789..000000000 --- a/m1/JavaScript-client/src/transaction_builder/builder_utils.ts +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { HexString } from "../utils"; -import { - TypeTag, - TypeTagBool, - TypeTagU8, - TypeTagU16, - TypeTagU32, - TypeTagU64, - TypeTagU128, - TypeTagU256, - TypeTagAddress, - AccountAddress, - TypeTagVector, - TypeTagStruct, - TransactionArgument, - TransactionArgumentBool, - TransactionArgumentU16, - TransactionArgumentU32, - TransactionArgumentU64, - TransactionArgumentU128, - TransactionArgumentU256, - TransactionArgumentAddress, - TransactionArgumentU8, - TransactionArgumentU8Vector, -} from "../aptos_types"; -import { Serializer } from "../bcs"; - -function assertType(val: any, types: string[] | string, message?: string) { - if (!types?.includes(typeof val)) { - throw new Error( - message || `Invalid arg: ${val} type should be ${types instanceof Array ? types.join(" or ") : types}`, - ); - } -} - -export function ensureBoolean(val: boolean | string): boolean { - assertType(val, ["boolean", "string"]); - if (typeof val === "boolean") { - return val; - } - - if (val === "true") { - return true; - } - if (val === "false") { - return false; - } - - throw new Error("Invalid boolean string."); -} - -export function ensureNumber(val: number | string): number { - assertType(val, ["number", "string"]); - if (typeof val === "number") { - return val; - } - - const res = Number.parseInt(val, 10); - if (Number.isNaN(res)) { - throw new Error("Invalid number string."); - } - - return res; -} - -export function ensureBigInt(val: number | bigint | string): bigint { - assertType(val, ["number", "bigint", "string"]); - return BigInt(val); -} - -export function serializeArg(argVal: any, argType: TypeTag, serializer: Serializer) { - if (argType instanceof TypeTagBool) { - serializer.serializeBool(ensureBoolean(argVal)); - return; - } - if (argType instanceof TypeTagU8) { - serializer.serializeU8(ensureNumber(argVal)); - return; - } - if (argType instanceof TypeTagU16) { - serializer.serializeU16(ensureNumber(argVal)); - return; - } - if (argType instanceof TypeTagU32) { - serializer.serializeU32(ensureNumber(argVal)); - return; - } - if (argType instanceof TypeTagU64) { - serializer.serializeU64(ensureBigInt(argVal)); - return; - } - if (argType instanceof TypeTagU128) { - serializer.serializeU128(ensureBigInt(argVal)); - return; - } - if (argType instanceof TypeTagU256) { - serializer.serializeU256(ensureBigInt(argVal)); - return; - } - if (argType instanceof TypeTagAddress) { - let addr: AccountAddress; - if (typeof argVal === "string" || argVal instanceof HexString) { - addr = AccountAddress.fromHex(argVal); - } else if (argVal instanceof AccountAddress) { - addr = argVal; - } else { - throw new Error("Invalid account address."); - } - addr.serialize(serializer); - return; - } - if (argType instanceof TypeTagVector) { - // We are serializing a vector - if (argType.value instanceof TypeTagU8) { - if (argVal instanceof Uint8Array) { - serializer.serializeBytes(argVal); - return; - } - - if (typeof argVal === "string") { - serializer.serializeStr(argVal); - return; - } - } - - if (!Array.isArray(argVal)) { - throw new Error("Invalid vector args."); - } - - serializer.serializeU32AsUleb128(argVal.length); - - argVal.forEach((arg) => serializeArg(arg, argType.value, serializer)); - return; - } - - if (argType instanceof TypeTagStruct) { - const { address, module_name: moduleName, name } = (argType as TypeTagStruct).value; - if ( - `${HexString.fromUint8Array(address.address).toShortString()}::${moduleName.value}::${name.value}` !== - "0x1::string::String" - ) { - throw new Error("The only supported struct arg is of type 0x1::string::String"); - } - assertType(argVal, ["string"]); - - serializer.serializeStr(argVal); - return; - } - throw new Error("Unsupported arg type."); -} - -export function argToTransactionArgument(argVal: any, argType: TypeTag): TransactionArgument { - if (argType instanceof TypeTagBool) { - return new TransactionArgumentBool(ensureBoolean(argVal)); - } - if (argType instanceof TypeTagU8) { - return new TransactionArgumentU8(ensureNumber(argVal)); - } - if (argType instanceof TypeTagU16) { - return new TransactionArgumentU16(ensureNumber(argVal)); - } - if (argType instanceof TypeTagU32) { - return new TransactionArgumentU32(ensureNumber(argVal)); - } - if (argType instanceof TypeTagU64) { - return new TransactionArgumentU64(ensureBigInt(argVal)); - } - if (argType instanceof TypeTagU128) { - return new TransactionArgumentU128(ensureBigInt(argVal)); - } - if (argType instanceof TypeTagU256) { - return new TransactionArgumentU256(ensureBigInt(argVal)); - } - if (argType instanceof TypeTagAddress) { - let addr: AccountAddress; - if (typeof argVal === "string" || argVal instanceof HexString) { - addr = AccountAddress.fromHex(argVal); - } else if (argVal instanceof AccountAddress) { - addr = argVal; - } else { - throw new Error("Invalid account address."); - } - return new TransactionArgumentAddress(addr); - } - if (argType instanceof TypeTagVector && argType.value instanceof TypeTagU8) { - if (!(argVal instanceof Uint8Array)) { - throw new Error(`${argVal} should be an instance of Uint8Array`); - } - return new TransactionArgumentU8Vector(argVal); - } - - throw new Error("Unknown type for TransactionArgument."); -} diff --git a/m1/JavaScript-client/src/transaction_builder/index.ts b/m1/JavaScript-client/src/transaction_builder/index.ts deleted file mode 100644 index eea089f9c..000000000 --- a/m1/JavaScript-client/src/transaction_builder/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -export * from "./builder"; -export * as TxnBuilderTypes from "../aptos_types"; diff --git a/m1/JavaScript-client/src/utils/api-endpoints.ts b/m1/JavaScript-client/src/utils/api-endpoints.ts deleted file mode 100644 index 7645b8278..000000000 --- a/m1/JavaScript-client/src/utils/api-endpoints.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const NetworkToIndexerAPI: Record = { - mainnet: "https://indexer.mainnet.aptoslabs.com/v1/graphql", - testnet: "https://indexer-testnet.staging.gcp.aptosdev.com/v1/graphql", - devnet: "https://indexer-devnet.staging.gcp.aptosdev.com/v1/graphql", -}; - -export const NetworkToNodeAPI: Record = { - mainnet: "https://fullnode.mainnet.aptoslabs.com/v1", - testnet: "https://fullnode.testnet.aptoslabs.com/v1", - devnet: "https://fullnode.devnet.aptoslabs.com/v1", -}; - -export enum Network { - MAINNET = "mainnet", - TESTNET = "testnet", - DEVNET = "devnet", -} - -export interface CustomEndpoints { - fullnodeUrl: string; - indexerUrl: string; -} diff --git a/m1/JavaScript-client/src/utils/hd-key.ts b/m1/JavaScript-client/src/utils/hd-key.ts deleted file mode 100644 index 32ffd9324..000000000 --- a/m1/JavaScript-client/src/utils/hd-key.ts +++ /dev/null @@ -1,79 +0,0 @@ -import nacl from "tweetnacl"; -import { hmac } from "@noble/hashes/hmac"; -import { sha512 } from "@noble/hashes/sha512"; -import { hexToBytes } from "@noble/hashes/utils"; - -type Hex = string; -type Path = string; - -type Keys = { - key: Uint8Array; - chainCode: Uint8Array; -}; - -const pathRegex = /^m(\/[0-9]+')+$/; - -const replaceDerive = (val: string): string => val.replace("'", ""); - -const HMAC_KEY = "ed25519 seed"; -const HARDENED_OFFSET = 0x80000000; - -export const getMasterKeyFromSeed = (seed: Hex): Keys => { - const h = hmac.create(sha512, HMAC_KEY); - const I = h.update(hexToBytes(seed)).digest(); - const IL = I.slice(0, 32); - const IR = I.slice(32); - return { - key: IL, - chainCode: IR, - }; -}; - -export const CKDPriv = ({ key, chainCode }: Keys, index: number): Keys => { - const buffer = new ArrayBuffer(4); - new DataView(buffer).setUint32(0, index); - const indexBytes = new Uint8Array(buffer); - const zero = new Uint8Array([0]); - const data = new Uint8Array([...zero, ...key, ...indexBytes]); - - const I = hmac.create(sha512, chainCode).update(data).digest(); - const IL = I.slice(0, 32); - const IR = I.slice(32); - return { - key: IL, - chainCode: IR, - }; -}; - -export const getPublicKey = (privateKey: Uint8Array, withZeroByte = true): Uint8Array => { - const keyPair = nacl.sign.keyPair.fromSeed(privateKey); - const signPk = keyPair.secretKey.subarray(32); - const zero = new Uint8Array([0]); - return withZeroByte ? new Uint8Array([...zero, ...signPk]) : signPk; -}; - -export const isValidPath = (path: string): boolean => { - if (!pathRegex.test(path)) { - return false; - } - return !path - .split("/") - .slice(1) - .map(replaceDerive) - .some(Number.isNaN as any); -}; - -export const derivePath = (path: Path, seed: Hex, offset = HARDENED_OFFSET): Keys => { - if (!isValidPath(path)) { - throw new Error("Invalid derivation path"); - } - - const { key, chainCode } = getMasterKeyFromSeed(seed); - const segments = path - .split("/") - .slice(1) - .map(replaceDerive) - .map((el) => parseInt(el, 10)); - - return segments.reduce((parentKeys, segment) => CKDPriv(parentKeys, segment + offset), { key, chainCode }); -}; diff --git a/m1/JavaScript-client/src/utils/hex_string.ts b/m1/JavaScript-client/src/utils/hex_string.ts deleted file mode 100644 index 2fa228b60..000000000 --- a/m1/JavaScript-client/src/utils/hex_string.ts +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; -import { HexEncodedBytes } from "../generated"; - -// eslint-disable-next-line no-use-before-define -export type MaybeHexString = HexString | string | HexEncodedBytes; - -/** - * A util class for working with hex strings. - * Hex strings are strings that are prefixed with `0x` - */ -export class HexString { - /// We want to make sure this hexString has the `0x` hex prefix - private readonly hexString: string; - - /** - * Creates new hex string from Buffer - * @param buffer A buffer to convert - * @returns New HexString - */ - static fromBuffer(buffer: Uint8Array): HexString { - return HexString.fromUint8Array(buffer); - } - - /** - * Creates new hex string from Uint8Array - * @param arr Uint8Array to convert - * @returns New HexString - */ - static fromUint8Array(arr: Uint8Array): HexString { - return new HexString(bytesToHex(arr)); - } - - /** - * Ensures `hexString` is instance of `HexString` class - * @param hexString String to check - * @returns New HexString if `hexString` is regular string or `hexString` if it is HexString instance - * @example - * ``` - * const regularString = "string"; - * const hexString = new HexString("string"); // "0xstring" - * HexString.ensure(regularString); // "0xstring" - * HexString.ensure(hexString); // "0xstring" - * ``` - */ - static ensure(hexString: MaybeHexString): HexString { - if (typeof hexString === "string") { - return new HexString(hexString); - } - return hexString; - } - - /** - * Creates new HexString instance from regular string. If specified string already starts with "0x" prefix, - * it will not add another one - * @param hexString String to convert - * @example - * ``` - * const string = "string"; - * new HexString(string); // "0xstring" - * ``` - */ - constructor(hexString: string | HexEncodedBytes) { - if (hexString.startsWith("0x")) { - this.hexString = hexString; - } else { - this.hexString = `0x${hexString}`; - } - } - - /** - * Getter for inner hexString - * @returns Inner hex string - */ - hex(): string { - return this.hexString; - } - - /** - * Getter for inner hexString without prefix - * @returns Inner hex string without prefix - * @example - * ``` - * const hexString = new HexString("string"); // "0xstring" - * hexString.noPrefix(); // "string" - * ``` - */ - noPrefix(): string { - return this.hexString.slice(2); - } - - /** - * Overrides default `toString` method - * @returns Inner hex string - */ - toString(): string { - return this.hex(); - } - - /** - * Trimmes extra zeroes in the begining of a string - * @returns Inner hexString without leading zeroes - * @example - * ``` - * new HexString("0x000000string").toShortString(); // result = "0xstring" - * ``` - */ - toShortString(): string { - const trimmed = this.hexString.replace(/^0x0*/, ""); - return `0x${trimmed}`; - } - - /** - * Converts hex string to a Uint8Array - * @returns Uint8Array from inner hexString without prefix - */ - toUint8Array(): Uint8Array { - return Uint8Array.from(hexToBytes(this.noPrefix())); - } -} diff --git a/m1/JavaScript-client/src/utils/index.ts b/m1/JavaScript-client/src/utils/index.ts deleted file mode 100644 index dfeaacc64..000000000 --- a/m1/JavaScript-client/src/utils/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./misc"; -export * from "./memoize-decorator"; -export * from "./pagination_helpers"; -export * from "./api-endpoints"; -export * from "./hex_string"; diff --git a/m1/JavaScript-client/src/utils/memoize-decorator.ts b/m1/JavaScript-client/src/utils/memoize-decorator.ts deleted file mode 100644 index 291c87819..000000000 --- a/m1/JavaScript-client/src/utils/memoize-decorator.ts +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Credits to https://github.com/darrylhodgins/typescript-memoize - */ - -/* eslint-disable no-param-reassign */ -/* eslint-disable no-restricted-syntax */ - -interface MemoizeArgs { - // ttl in milliseconds for cached items. After `ttlMs`, cached items are evicted automatically. If no `ttlMs` - // is provided, cached items won't get auto-evicted. - ttlMs?: number; - // produces the cache key based on `args`. - hashFunction?: boolean | ((...args: any[]) => any); - // cached items can be taged with `tags`. `tags` can be used to evict cached items - tags?: string[]; -} - -export function Memoize(args?: MemoizeArgs | MemoizeArgs["hashFunction"]) { - let hashFunction: MemoizeArgs["hashFunction"]; - let ttlMs: MemoizeArgs["ttlMs"]; - let tags: MemoizeArgs["tags"]; - - if (typeof args === "object") { - hashFunction = args.hashFunction; - ttlMs = args.ttlMs; - tags = args.tags; - } else { - hashFunction = args; - } - - return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) => { - if (descriptor.value != null) { - descriptor.value = getNewFunction(descriptor.value, hashFunction, ttlMs, tags); - } else if (descriptor.get != null) { - descriptor.get = getNewFunction(descriptor.get, hashFunction, ttlMs, tags); - } else { - throw new Error("Only put a Memoize() decorator on a method or get accessor."); - } - }; -} - -export function MemoizeExpiring(ttlMs: number, hashFunction?: MemoizeArgs["hashFunction"]) { - return Memoize({ - ttlMs, - hashFunction, - }); -} - -const clearCacheTagsMap: Map[]> = new Map(); - -export function clear(tags: string[]): number { - const cleared: Set> = new Set(); - for (const tag of tags) { - const maps = clearCacheTagsMap.get(tag); - if (maps) { - for (const mp of maps) { - if (!cleared.has(mp)) { - mp.clear(); - cleared.add(mp); - } - } - } - } - return cleared.size; -} - -function getNewFunction( - originalMethod: () => void, - hashFunction?: MemoizeArgs["hashFunction"], - ttlMs: number = 0, - tags?: MemoizeArgs["tags"], -) { - const propMapName = Symbol("__memoized_map__"); - - // The function returned here gets called instead of originalMethod. - // eslint-disable-next-line func-names - return function (...args: any[]) { - let returnedValue: any; - - // @ts-ignore - const that: any = this; - - // Get or create map - // eslint-disable-next-line no-prototype-builtins - if (!that.hasOwnProperty(propMapName)) { - Object.defineProperty(that, propMapName, { - configurable: false, - enumerable: false, - writable: false, - value: new Map(), - }); - } - const myMap: Map = that[propMapName]; - - if (Array.isArray(tags)) { - for (const tag of tags) { - if (clearCacheTagsMap.has(tag)) { - clearCacheTagsMap.get(tag)!.push(myMap); - } else { - clearCacheTagsMap.set(tag, [myMap]); - } - } - } - - if (hashFunction || args.length > 0 || ttlMs > 0) { - let hashKey: any; - - // If true is passed as first parameter, will automatically use every argument, passed to string - if (hashFunction === true) { - hashKey = args.map((a) => a.toString()).join("!"); - } else if (hashFunction) { - hashKey = hashFunction.apply(that, args); - } else { - // eslint-disable-next-line prefer-destructuring - hashKey = args[0]; - } - - const timestampKey = `${hashKey}__timestamp`; - let isExpired: boolean = false; - if (ttlMs > 0) { - if (!myMap.has(timestampKey)) { - // "Expired" since it was never called before - isExpired = true; - } else { - const timestamp = myMap.get(timestampKey); - isExpired = Date.now() - timestamp > ttlMs; - } - } - - if (myMap.has(hashKey) && !isExpired) { - returnedValue = myMap.get(hashKey); - } else { - returnedValue = originalMethod.apply(that, args as any); - myMap.set(hashKey, returnedValue); - if (ttlMs > 0) { - myMap.set(timestampKey, Date.now()); - } - } - } else { - const hashKey = that; - if (myMap.has(hashKey)) { - returnedValue = myMap.get(hashKey); - } else { - returnedValue = originalMethod.apply(that, args as any); - myMap.set(hashKey, returnedValue); - } - } - - return returnedValue; - }; -} diff --git a/m1/JavaScript-client/src/utils/misc.ts b/m1/JavaScript-client/src/utils/misc.ts deleted file mode 100644 index fca18b0f3..000000000 --- a/m1/JavaScript-client/src/utils/misc.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -export type Nullable = { [P in keyof T]: T[P] | null }; - -export type AnyObject = { [key: string]: any }; - -export async function sleep(timeMs: number): Promise { - return new Promise((resolve) => { - setTimeout(resolve, timeMs); - }); -} - -export const DEFAULT_VERSION_PATH_BASE = "/v1"; - -export function fixNodeUrl(nodeUrl: string): string { - let out = `${nodeUrl}`; - if (out.endsWith("/")) { - out = out.substring(0, out.length - 1); - } - if (!out.endsWith(DEFAULT_VERSION_PATH_BASE)) { - out = `${out}${DEFAULT_VERSION_PATH_BASE}`; - } - return out; -} - -export const DEFAULT_MAX_GAS_AMOUNT = 200000; -// Transaction expire timestamp -export const DEFAULT_TXN_EXP_SEC_FROM_NOW = 20; -// How long does SDK wait for txhn to finish -export const DEFAULT_TXN_TIMEOUT_SEC = 20; -export const APTOS_COIN = "0x1::aptos_coin::AptosCoin"; diff --git a/m1/JavaScript-client/src/utils/pagination_helpers.ts b/m1/JavaScript-client/src/utils/pagination_helpers.ts deleted file mode 100644 index 3d903715d..000000000 --- a/m1/JavaScript-client/src/utils/pagination_helpers.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { AnyNumber } from "../bcs"; -import { HexString, MaybeHexString } from "./hex_string"; - -/// This function is a helper for paginating using a function wrapping an API -export async function paginateWithCursor( - apiFunction: ( - address: string, - ledgerVersion?: string | undefined, - start?: string | undefined, - limit?: number | undefined, - ) => Promise, - accountAddress: MaybeHexString, - limitPerRequest: number, - query?: { ledgerVersion?: AnyNumber }, -): Promise { - const out = []; - let cursor: string | undefined; - // eslint-disable-next-line no-constant-condition - while (true) { - // eslint-disable-next-line no-await-in-loop - const response = await apiFunction( - HexString.ensure(accountAddress).hex(), - query?.ledgerVersion?.toString(), - cursor, - limitPerRequest, - ); - // Response is the main response, i.e. the T[]. Attached to that are the headers as `__headers`. - // eslint-disable-next-line no-underscore-dangle - cursor = (response as any).__headers["x-aptos-cursor"]; - // Now that we have the cursor (if any), we remove the headers before - // adding these to the output of this function. - // eslint-disable-next-line no-underscore-dangle - delete (response as any).__headers; - out.push(...response); - if (cursor === null || cursor === undefined) { - break; - } - } - return out; -} diff --git a/m1/JavaScript-client/src/utils/property_map_serde.ts b/m1/JavaScript-client/src/utils/property_map_serde.ts deleted file mode 100644 index b3b0d3d70..000000000 --- a/m1/JavaScript-client/src/utils/property_map_serde.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Bytes, Deserializer, Serializer } from "../bcs"; -import { serializeArg } from "../transaction_builder/builder_utils"; -import { - stringStructTag, - TypeTag, - TypeTagAddress, - TypeTagBool, - TypeTagParser, - TypeTagStruct, - TypeTagU128, - TypeTagU64, - TypeTagU8, -} from "../aptos_types"; -import { HexString } from "./hex_string"; - -export class PropertyValue { - type: string; - - value: any; - - constructor(type: string, value: string) { - this.type = type; - this.value = value; - } -} - -export class PropertyMap { - data: { [key: string]: PropertyValue }; - - constructor() { - this.data = {}; - } - - setProperty(key: string, value: PropertyValue) { - this.data[key] = value; - } -} - -export function getPropertyType(typ: string): TypeTag { - let typeTag: TypeTag; - if (typ === "string" || typ === "String") { - typeTag = new TypeTagStruct(stringStructTag); - } else { - typeTag = new TypeTagParser(typ).parseTypeTag(); - } - return typeTag; -} - -export function getPropertyValueRaw(values: Array, types: Array): Array { - if (values.length !== types.length) { - throw new Error("Length of property values and types not match"); - } - - const results = new Array(); - types.forEach((typ, index) => { - try { - const typeTag = getPropertyType(typ); - const serializer = new Serializer(); - serializeArg(values[index], typeTag, serializer); - results.push(serializer.getBytes()); - } catch (error) { - // if not support type, just use the raw string bytes - results.push(new TextEncoder().encode(values[index])); - } - }); - return results; -} - -export function getSinglePropertyValueRaw(value: string, type: string): Uint8Array { - if (!value || !type) { - throw new Error("value or type can not be empty"); - } - - try { - const typeTag = getPropertyType(type); - const serializer = new Serializer(); - serializeArg(value, typeTag, serializer); - return serializer.getBytes(); - } catch (error) { - // if not support type, just use the raw string bytes - return new TextEncoder().encode(value); - } -} - -export function deserializePropertyMap(rawPropertyMap: any): PropertyMap { - const entries = rawPropertyMap.map.data; - const pm = new PropertyMap(); - entries.forEach((prop: any) => { - const { key } = prop; - const val: string = prop.value.value; - const typ: string = prop.value.type; - const typeTag = getPropertyType(typ); - const newValue = deserializeValueBasedOnTypeTag(typeTag, val); - const pv = new PropertyValue(typ, newValue); - pm.setProperty(key, pv); - }); - return pm; -} - -export function deserializeValueBasedOnTypeTag(tag: TypeTag, val: string): string { - const de = new Deserializer(new HexString(val).toUint8Array()); - let res: string = ""; - if (tag instanceof TypeTagU8) { - res = de.deserializeU8().toString(); - } else if (tag instanceof TypeTagU64) { - res = de.deserializeU64().toString(); - } else if (tag instanceof TypeTagU128) { - res = de.deserializeU128().toString(); - } else if (tag instanceof TypeTagBool) { - res = de.deserializeBool() ? "true" : "false"; - } else if (tag instanceof TypeTagAddress) { - res = HexString.fromUint8Array(de.deserializeFixedBytes(32)).hex(); - } else if (tag instanceof TypeTagStruct && (tag as TypeTagStruct).isStringTypeTag()) { - res = de.deserializeStr(); - } else { - res = val; - } - return res; -} diff --git a/m1/JavaScript-client/src/version.ts b/m1/JavaScript-client/src/version.ts deleted file mode 100644 index c58a1f0ac..000000000 --- a/m1/JavaScript-client/src/version.ts +++ /dev/null @@ -1,2 +0,0 @@ -// hardcoded for now, we would want to have it injected dynamically -export const VERSION = "1.8.5"; diff --git a/m1/JavaScript-client/tsconfig.json b/m1/JavaScript-client/tsconfig.json deleted file mode 100644 index f7996b6de..000000000 --- a/m1/JavaScript-client/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "allowJs": true, - "declaration": true, - "declarationMap": true, - "esModuleInterop": true, - "experimentalDecorators": true, - "module": "esnext", - "moduleResolution": "node", - "noImplicitAny": true, - "outDir": "./dist", - "sourceMap": true, - "strict": true, - "target": "es2020", - "pretty": true - }, - "include": ["src"] -} diff --git a/m1/JavaScript-client/tsup.config.js b/m1/JavaScript-client/tsup.config.js deleted file mode 100644 index b02abb274..000000000 --- a/m1/JavaScript-client/tsup.config.js +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from "tsup"; - -export default defineConfig({ - entry: ["src/index.ts"], - splitting: false, - sourcemap: true, - target: "es2018", -}); diff --git a/m1/JavaScript-client/yarn.lock b/m1/JavaScript-client/yarn.lock deleted file mode 100644 index cbd0bd57b..000000000 --- a/m1/JavaScript-client/yarn.lock +++ /dev/null @@ -1,6110 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== - dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@apidevtools/json-schema-ref-parser@9.0.9": - version "9.0.9" - resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#d720f9256e3609621280584f2b47ae165359268b" - integrity sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w== - dependencies: - "@jsdevtools/ono" "^7.1.3" - "@types/json-schema" "^7.0.6" - call-me-maybe "^1.0.1" - js-yaml "^4.1.0" - -"@ardatan/relay-compiler@12.0.0": - version "12.0.0" - resolved "https://registry.yarnpkg.com/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz#2e4cca43088e807adc63450e8cab037020e91106" - integrity sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q== - dependencies: - "@babel/core" "^7.14.0" - "@babel/generator" "^7.14.0" - "@babel/parser" "^7.14.0" - "@babel/runtime" "^7.0.0" - "@babel/traverse" "^7.14.0" - "@babel/types" "^7.0.0" - babel-preset-fbjs "^3.4.0" - chalk "^4.0.0" - fb-watchman "^2.0.0" - fbjs "^3.0.0" - glob "^7.1.1" - immutable "~3.7.6" - invariant "^2.2.4" - nullthrows "^1.1.1" - relay-runtime "12.0.0" - signedsource "^1.0.0" - yargs "^15.3.1" - -"@ardatan/sync-fetch@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz#3385d3feedceb60a896518a1db857ec1e945348f" - integrity sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA== - dependencies: - node-fetch "^2.6.1" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/code-frame@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/compat-data@^7.20.0": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" - integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== - -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.4.tgz#457ffe647c480dff59c2be092fc3acf71195c87f" - integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g== - -"@babel/core@^7.11.6", "@babel/core@^7.12.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.2.tgz#8dc9b1620a673f92d3624bd926dc49a52cf25b92" - integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.2" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-module-transforms" "^7.20.2" - "@babel/helpers" "^7.20.1" - "@babel/parser" "^7.20.2" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" - -"@babel/core@^7.14.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.4.tgz#c6dc73242507b8e2a27fd13a9c1814f9fa34a659" - integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-compilation-targets" "^7.21.4" - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helpers" "^7.21.0" - "@babel/parser" "^7.21.4" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.4" - "@babel/types" "^7.21.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" - -"@babel/generator@^7.14.0", "@babel/generator@^7.18.13", "@babel/generator@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.4.tgz#64a94b7448989f421f919d5239ef553b37bb26bc" - integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== - dependencies: - "@babel/types" "^7.21.4" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.20.1", "@babel/generator@^7.20.2", "@babel/generator@^7.7.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.2.tgz#c2e89e22613a039285c1e7b749e2cd0b30b9a481" - integrity sha512-SD75PMIK6i9H8G/tfGvB4KKl4Nw6Ssos9nGgYwxbgyTP0iX/Z55DveoH86rmUB/YHTQQ+ZC0F7xxaY8l2OF44Q== - dependencies: - "@babel/types" "^7.20.2" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" - -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz#770cd1ce0889097ceacb99418ee6934ef0572656" - integrity sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg== - dependencies: - "@babel/compat-data" "^7.21.4" - "@babel/helper-validator-option" "^7.21.0" - browserslist "^4.21.3" - lru-cache "^5.1.1" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" - integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== - dependencies: - "@babel/compat-data" "^7.20.0" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz#3a017163dc3c2ba7deb9a7950849a9586ea24c18" - integrity sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-member-expression-to-functions" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/helper-split-export-declaration" "^7.18.6" - -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" - integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== - dependencies: - "@babel/template" "^7.20.7" - "@babel/types" "^7.21.0" - -"@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz#319c6a940431a133897148515877d2f3269c3ba5" - integrity sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q== - dependencies: - "@babel/types" "^7.21.0" - -"@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-transforms@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" - integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" - -"@babel/helper-module-transforms@^7.21.2": - version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2" - integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.2" - "@babel/types" "^7.21.2" - -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== - -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331" - integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== - dependencies: - "@babel/types" "^7.20.2" - -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== - dependencies: - "@babel/types" "^7.20.0" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helper-validator-option@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" - integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== - -"@babel/helpers@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.1.tgz#2ab7a0fcb0a03b5bf76629196ed63c2d7311f4c9" - integrity sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg== - dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.0" - -"@babel/helpers@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" - integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== - dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.0" - "@babel/types" "^7.21.0" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.2.tgz#9aeb9b92f64412b5f81064d46f6a1ac0881337f4" - integrity sha512-afk318kh2uKbo7BEj2QtEi8HVCGrwHUffrYDy7dgVcSa2j9lY3LDjPzcyGdpX7xgm35aWqvciZJ4WKmdF/SxYg== - -"@babel/parser@^7.14.0", "@babel/parser@^7.16.8", "@babel/parser@^7.20.7", "@babel/parser@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17" - integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== - -"@babel/plugin-proposal-class-properties@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== - dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.7" - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.0.0", "@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz#3e37fca4f06d93567c1cd9b75156422e90a67107" - integrity sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== - dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" - integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" - integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - -"@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz#bea332b0e8b2dab3dafe55a163d8227531ab0551" - integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-block-scoping@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02" - integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-classes@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz#f469d0b07a4c5a7dbb21afad9e27e57b47031665" - integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz#704cc2fd155d1c996551db8276d55b9d46e4d0aa" - integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/template" "^7.20.7" - -"@babel/plugin-transform-destructuring@^7.0.0": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz#73b46d0fd11cd6ef57dea8a381b1215f4959d401" - integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz#6aeca0adcb81dc627c8986e770bfaa4d9812aff5" - integrity sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-flow" "^7.18.6" - -"@babel/plugin-transform-for-of@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz#964108c9988de1a60b4be2354a7d7e245f36e86e" - integrity sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-function-name@^7.0.0": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== - dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-literals@^7.0.0": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-member-expression-literals@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz#6ff5070e71e3192ef2b7e39820a06fb78e3058e7" - integrity sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA== - dependencies: - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-simple-access" "^7.20.2" - -"@babel/plugin-transform-object-super@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" - -"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.20.7": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz#18fc4e797cf6d6d972cb8c411dbe8a809fa157db" - integrity sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-property-literals@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-react-display-name@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" - integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-react-jsx@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz#656b42c2fdea0a6d8762075d58ef9d4e3c4ab8a2" - integrity sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-jsx" "^7.18.6" - "@babel/types" "^7.21.0" - -"@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-spread@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz#c2d83e0b99d3bf83e07b11995ee24bf7ca09401e" - integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - -"@babel/plugin-transform-template-literals@^7.0.0": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/runtime@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" - integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/template@^7.18.10", "@babel/template@^7.3.3": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" - -"@babel/template@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/traverse@^7.14.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.4.tgz#a836aca7b116634e97a6ed99976236b3282c9d36" - integrity sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q== - dependencies: - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.21.4" - "@babel/types" "^7.21.4" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.20.1", "@babel/traverse@^7.7.2": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.1.tgz#9b15ccbf882f6d107eeeecf263fbcdd208777ec8" - integrity sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.1" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.1" - "@babel/types" "^7.20.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842" - integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog== - dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" - -"@babel/types@^7.16.8", "@babel/types@^7.18.13", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.4.tgz#2d5d6bb7908699b3b416409ffd3b5daa25b030d4" - integrity sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== - dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@esbuild/android-arm@0.15.13": - version "0.15.13" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.13.tgz#ce11237a13ee76d5eae3908e47ba4ddd380af86a" - integrity sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw== - -"@esbuild/linux-loong64@0.15.13": - version "0.15.13" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz#64e8825bf0ce769dac94ee39d92ebe6272020dfc" - integrity sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag== - -"@eslint/eslintrc@^1.3.1": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" - integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.4.0" - globals "^13.15.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@graphql-codegen/add@^3.2.1": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-3.2.3.tgz#f1ecee085987e7c21841edc4b1fd48877c663e1a" - integrity sha512-sQOnWpMko4JLeykwyjFTxnhqjd/3NOG2OyMuvK76Wnnwh8DRrNf2VEs2kmSvLl7MndMlOj7Kh5U154dVcvhmKQ== - dependencies: - "@graphql-codegen/plugin-helpers" "^3.1.1" - tslib "~2.4.0" - -"@graphql-codegen/cli@^2.13.5": - version "2.16.5" - resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-2.16.5.tgz#b3b5eeec357af01c1cb72f6a4ea96e52bd49e662" - integrity sha512-XYPIp+q7fB0xAGSAoRykiTe4oY80VU+z+dw5nuv4mLY0+pv7+pa2C6Nwhdw7a65lXOhFviBApWCCZeqd54SMnA== - dependencies: - "@babel/generator" "^7.18.13" - "@babel/template" "^7.18.10" - "@babel/types" "^7.18.13" - "@graphql-codegen/core" "^2.6.8" - "@graphql-codegen/plugin-helpers" "^3.1.2" - "@graphql-tools/apollo-engine-loader" "^7.3.6" - "@graphql-tools/code-file-loader" "^7.3.13" - "@graphql-tools/git-loader" "^7.2.13" - "@graphql-tools/github-loader" "^7.3.20" - "@graphql-tools/graphql-file-loader" "^7.5.0" - "@graphql-tools/json-file-loader" "^7.4.1" - "@graphql-tools/load" "^7.8.0" - "@graphql-tools/prisma-loader" "^7.2.49" - "@graphql-tools/url-loader" "^7.13.2" - "@graphql-tools/utils" "^9.0.0" - "@whatwg-node/fetch" "^0.6.0" - chalk "^4.1.0" - chokidar "^3.5.2" - cosmiconfig "^7.0.0" - cosmiconfig-typescript-loader "^4.3.0" - debounce "^1.2.0" - detect-indent "^6.0.0" - graphql-config "^4.4.0" - inquirer "^8.0.0" - is-glob "^4.0.1" - json-to-pretty-yaml "^1.2.2" - listr2 "^4.0.5" - log-symbols "^4.0.0" - shell-quote "^1.7.3" - string-env-interpolation "^1.0.1" - ts-log "^2.2.3" - ts-node "^10.9.1" - tslib "^2.4.0" - yaml "^1.10.0" - yargs "^17.0.0" - -"@graphql-codegen/core@^2.6.8": - version "2.6.8" - resolved "https://registry.yarnpkg.com/@graphql-codegen/core/-/core-2.6.8.tgz#00c4011e3619ddbc6af5e41b2f254d6f6759556e" - integrity sha512-JKllNIipPrheRgl+/Hm/xuWMw9++xNQ12XJR/OHHgFopOg4zmN3TdlRSyYcv/K90hCFkkIwhlHFUQTfKrm8rxQ== - dependencies: - "@graphql-codegen/plugin-helpers" "^3.1.1" - "@graphql-tools/schema" "^9.0.0" - "@graphql-tools/utils" "^9.1.1" - tslib "~2.4.0" - -"@graphql-codegen/import-types-preset@^2.2.3": - version "2.2.6" - resolved "https://registry.yarnpkg.com/@graphql-codegen/import-types-preset/-/import-types-preset-2.2.6.tgz#aab292d93f79bffc09bc12a51843c3272b526475" - integrity sha512-Lo2ITOln3UVdyyEPiijj8bVhVg0Ghp/JzHXA2LXxrJVCRbXizQhVC2vjiaWTjMskPt9Zub0yIoce4+RrbsXKcg== - dependencies: - "@graphql-codegen/add" "^3.2.1" - "@graphql-codegen/plugin-helpers" "^2.7.2" - "@graphql-codegen/visitor-plugin-common" "2.13.1" - tslib "~2.4.0" - -"@graphql-codegen/plugin-helpers@^2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz#6544f739d725441c826a8af6a49519f588ff9bed" - integrity sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg== - dependencies: - "@graphql-tools/utils" "^8.8.0" - change-case-all "1.0.14" - common-tags "1.8.2" - import-from "4.0.0" - lodash "~4.17.0" - tslib "~2.4.0" - -"@graphql-codegen/plugin-helpers@^3.0.0", "@graphql-codegen/plugin-helpers@^3.1.1", "@graphql-codegen/plugin-helpers@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz#69a2e91178f478ea6849846ade0a59a844d34389" - integrity sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg== - dependencies: - "@graphql-tools/utils" "^9.0.0" - change-case-all "1.0.15" - common-tags "1.8.2" - import-from "4.0.0" - lodash "~4.17.0" - tslib "~2.4.0" - -"@graphql-codegen/schema-ast@^2.6.1": - version "2.6.1" - resolved "https://registry.yarnpkg.com/@graphql-codegen/schema-ast/-/schema-ast-2.6.1.tgz#8ba1b38827c034b51ecd3ce88622c2ae6cd3fe1a" - integrity sha512-5TNW3b1IHJjCh07D2yQNGDQzUpUl2AD+GVe1Dzjqyx/d2Fn0TPMxLsHsKPS4Plg4saO8FK/QO70wLsP7fdbQ1w== - dependencies: - "@graphql-codegen/plugin-helpers" "^3.1.2" - "@graphql-tools/utils" "^9.0.0" - tslib "~2.4.0" - -"@graphql-codegen/typescript-graphql-request@^4.5.8": - version "4.5.9" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-graphql-request/-/typescript-graphql-request-4.5.9.tgz#d8a9488b7419cabf2ca98ae3936e82b9d244f2e9" - integrity sha512-Vtv5qymUXcR4UFdHOlJHzK5TN+CZUwMwFDGb3n4Gjcr4yln1BWbUb7DXgD0GHzpXwDIj5G2XmJnFtr0jihBfrg== - dependencies: - "@graphql-codegen/plugin-helpers" "^3.0.0" - "@graphql-codegen/visitor-plugin-common" "2.13.1" - auto-bind "~4.0.0" - tslib "~2.4.0" - -"@graphql-codegen/typescript-operations@^2.5.3": - version "2.5.13" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-2.5.13.tgz#f286c37f9c023356aacaa983ebd32e9e021a05ca" - integrity sha512-3vfR6Rx6iZU0JRt29GBkFlrSNTM6t+MSLF86ChvL4d/Jfo/JYAGuB3zNzPhirHYzJPCvLOAx2gy9ID1ltrpYiw== - dependencies: - "@graphql-codegen/plugin-helpers" "^3.1.2" - "@graphql-codegen/typescript" "^2.8.8" - "@graphql-codegen/visitor-plugin-common" "2.13.8" - auto-bind "~4.0.0" - tslib "~2.4.0" - -"@graphql-codegen/typescript@^2.7.3", "@graphql-codegen/typescript@^2.8.8": - version "2.8.8" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-2.8.8.tgz#8c3b9153e334db43c65f8f31ced69b4c60d14861" - integrity sha512-A0oUi3Oy6+DormOlrTC4orxT9OBZkIglhbJBcDmk34jAKKUgesukXRd4yOhmTrnbchpXz2T8IAOFB3FWIaK4Rw== - dependencies: - "@graphql-codegen/plugin-helpers" "^3.1.2" - "@graphql-codegen/schema-ast" "^2.6.1" - "@graphql-codegen/visitor-plugin-common" "2.13.8" - auto-bind "~4.0.0" - tslib "~2.4.0" - -"@graphql-codegen/visitor-plugin-common@2.13.1": - version "2.13.1" - resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.1.tgz#2228660f6692bcdb96b1f6d91a0661624266b76b" - integrity sha512-mD9ufZhDGhyrSaWQGrU1Q1c5f01TeWtSWy/cDwXYjJcHIj1Y/DG2x0tOflEfCvh5WcnmHNIw4lzDsg1W7iFJEg== - dependencies: - "@graphql-codegen/plugin-helpers" "^2.7.2" - "@graphql-tools/optimize" "^1.3.0" - "@graphql-tools/relay-operation-optimizer" "^6.5.0" - "@graphql-tools/utils" "^8.8.0" - auto-bind "~4.0.0" - change-case-all "1.0.14" - dependency-graph "^0.11.0" - graphql-tag "^2.11.0" - parse-filepath "^1.0.2" - tslib "~2.4.0" - -"@graphql-codegen/visitor-plugin-common@2.13.8": - version "2.13.8" - resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.8.tgz#09bc6317b227e5a278f394f4cef0d6c2d1910597" - integrity sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ== - dependencies: - "@graphql-codegen/plugin-helpers" "^3.1.2" - "@graphql-tools/optimize" "^1.3.0" - "@graphql-tools/relay-operation-optimizer" "^6.5.0" - "@graphql-tools/utils" "^9.0.0" - auto-bind "~4.0.0" - change-case-all "1.0.15" - dependency-graph "^0.11.0" - graphql-tag "^2.11.0" - parse-filepath "^1.0.2" - tslib "~2.4.0" - -"@graphql-tools/apollo-engine-loader@^7.3.6": - version "7.3.26" - resolved "https://registry.yarnpkg.com/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.3.26.tgz#91e54460d5579933e42a2010b8688c3459c245d8" - integrity sha512-h1vfhdJFjnCYn9b5EY1Z91JTF0KB3hHVJNQIsiUV2mpQXZdeOXQoaWeYEKaiI5R6kwBw5PP9B0fv3jfUIG8LyQ== - dependencies: - "@ardatan/sync-fetch" "^0.0.1" - "@graphql-tools/utils" "^9.2.1" - "@whatwg-node/fetch" "^0.8.0" - tslib "^2.4.0" - -"@graphql-tools/batch-execute@^8.5.21": - version "8.5.21" - resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-8.5.21.tgz#dce327cab43bf6d7389e607f603369724c93ce06" - integrity sha512-DDyCPUSUjc0he/I9byguxohW/owQyVEO/gJcXLFAbHtTjORci3gRaRwLw24j0WaP+ZAlxYTMQs1HSlyJFaUArA== - dependencies: - "@graphql-tools/utils" "^9.2.1" - dataloader "^2.2.2" - tslib "^2.4.0" - value-or-promise "^1.0.12" - -"@graphql-tools/code-file-loader@^7.3.13": - version "7.3.23" - resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-7.3.23.tgz#33793f9a1f8e74981f8ae6ec4ab7061f9713db15" - integrity sha512-8Wt1rTtyTEs0p47uzsPJ1vAtfAx0jmxPifiNdmo9EOCuUPyQGEbMaik/YkqZ7QUFIEYEQu+Vgfo8tElwOPtx5Q== - dependencies: - "@graphql-tools/graphql-tag-pluck" "7.5.2" - "@graphql-tools/utils" "^9.2.1" - globby "^11.0.3" - tslib "^2.4.0" - unixify "^1.0.0" - -"@graphql-tools/delegate@^9.0.31": - version "9.0.34" - resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-9.0.34.tgz#50a877b3645bf5275d12c6f8a422cefdfe16bdad" - integrity sha512-qVTeq+0nxiDo54f28r0tOoXE6nipzGyDp5uuNMJJRvmIWjFGiyOBI8IsynPvLb2nCwhcpaTVJ2Bqswk/3DNO4w== - dependencies: - "@graphql-tools/batch-execute" "^8.5.21" - "@graphql-tools/executor" "^0.0.19" - "@graphql-tools/schema" "^9.0.19" - "@graphql-tools/utils" "^9.2.1" - dataloader "^2.2.2" - tslib "^2.5.0" - value-or-promise "^1.0.12" - -"@graphql-tools/executor-graphql-ws@^0.0.14": - version "0.0.14" - resolved "https://registry.yarnpkg.com/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-0.0.14.tgz#e0f53fc4cfc8a06cc461b2bc1edb4bb9a8e837ed" - integrity sha512-P2nlkAsPZKLIXImFhj0YTtny5NQVGSsKnhi7PzXiaHSXc6KkzqbWZHKvikD4PObanqg+7IO58rKFpGXP7eeO+w== - dependencies: - "@graphql-tools/utils" "^9.2.1" - "@repeaterjs/repeater" "3.0.4" - "@types/ws" "^8.0.0" - graphql-ws "5.12.1" - isomorphic-ws "5.0.0" - tslib "^2.4.0" - ws "8.13.0" - -"@graphql-tools/executor-http@^0.1.7", "@graphql-tools/executor-http@^0.1.9": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@graphql-tools/executor-http/-/executor-http-0.1.9.tgz#ddd74ef376b4a2ed59c622acbcca068890854a30" - integrity sha512-tNzMt5qc1ptlHKfpSv9wVBVKCZ7gks6Yb/JcYJluxZIT4qRV+TtOFjpptfBU63usgrGVOVcGjzWc/mt7KhmmpQ== - dependencies: - "@graphql-tools/utils" "^9.2.1" - "@repeaterjs/repeater" "^3.0.4" - "@whatwg-node/fetch" "^0.8.1" - dset "^3.1.2" - extract-files "^11.0.0" - meros "^1.2.1" - tslib "^2.4.0" - value-or-promise "^1.0.12" - -"@graphql-tools/executor-legacy-ws@^0.0.11": - version "0.0.11" - resolved "https://registry.yarnpkg.com/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-0.0.11.tgz#a1e12be8279e92a363a23d4105461a34cd9e389e" - integrity sha512-4ai+NnxlNfvIQ4c70hWFvOZlSUN8lt7yc+ZsrwtNFbFPH/EroIzFMapAxM9zwyv9bH38AdO3TQxZ5zNxgBdvUw== - dependencies: - "@graphql-tools/utils" "^9.2.1" - "@types/ws" "^8.0.0" - isomorphic-ws "5.0.0" - tslib "^2.4.0" - ws "8.13.0" - -"@graphql-tools/executor@^0.0.19": - version "0.0.19" - resolved "https://registry.yarnpkg.com/@graphql-tools/executor/-/executor-0.0.19.tgz#df3e0aa03923cebc6a4ff9bad76a8fd4c8e34eb5" - integrity sha512-JYxuxseH7GGQ9olamrK73xUA05q/bKZ1efnYglSD6/05pb+Gz+VXDK8Y3pWha10aM6c529t//6hzJ5T/99Be5Q== - dependencies: - "@graphql-tools/utils" "^9.2.1" - "@graphql-typed-document-node/core" "3.2.0" - "@repeaterjs/repeater" "^3.0.4" - tslib "^2.4.0" - value-or-promise "^1.0.12" - -"@graphql-tools/git-loader@^7.2.13": - version "7.2.22" - resolved "https://registry.yarnpkg.com/@graphql-tools/git-loader/-/git-loader-7.2.22.tgz#b937273adae69a992d5d1d2e43bc1df21b6654d3" - integrity sha512-9rpHggHiOeqA7/ZlKD3c5yXk5bPGw0zkIgKMerjCmFAQAZ6CEVfsa7nAzEWQxn6rpdaBft4/0A56rPMrsUwGBA== - dependencies: - "@graphql-tools/graphql-tag-pluck" "7.5.2" - "@graphql-tools/utils" "^9.2.1" - is-glob "4.0.3" - micromatch "^4.0.4" - tslib "^2.4.0" - unixify "^1.0.0" - -"@graphql-tools/github-loader@^7.3.20": - version "7.3.28" - resolved "https://registry.yarnpkg.com/@graphql-tools/github-loader/-/github-loader-7.3.28.tgz#a7166b136e8442bd8b3ab943ad3b66c84bcabfcf" - integrity sha512-OK92Lf9pmxPQvjUNv05b3tnVhw0JRfPqOf15jZjyQ8BfdEUrJoP32b4dRQQem/wyRL24KY4wOfArJNqzpsbwCA== - dependencies: - "@ardatan/sync-fetch" "^0.0.1" - "@graphql-tools/executor-http" "^0.1.9" - "@graphql-tools/graphql-tag-pluck" "^7.4.6" - "@graphql-tools/utils" "^9.2.1" - "@whatwg-node/fetch" "^0.8.0" - tslib "^2.4.0" - value-or-promise "^1.0.12" - -"@graphql-tools/graphql-file-loader@^7.3.7", "@graphql-tools/graphql-file-loader@^7.5.0": - version "7.5.17" - resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.5.17.tgz#7c281617ea3ab4db4d42a2bdb49850f2b937f0f9" - integrity sha512-hVwwxPf41zOYgm4gdaZILCYnKB9Zap7Ys9OhY1hbwuAuC4MMNY9GpUjoTU3CQc3zUiPoYStyRtUGkHSJZ3HxBw== - dependencies: - "@graphql-tools/import" "6.7.18" - "@graphql-tools/utils" "^9.2.1" - globby "^11.0.3" - tslib "^2.4.0" - unixify "^1.0.0" - -"@graphql-tools/graphql-tag-pluck@7.5.2", "@graphql-tools/graphql-tag-pluck@^7.4.6": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.5.2.tgz#502f1e066e19d832ebdeba5f571d7636dc27572d" - integrity sha512-RW+H8FqOOLQw0BPXaahYepVSRjuOHw+7IL8Opaa5G5uYGOBxoXR7DceyQ7BcpMgktAOOmpDNQ2WtcboChOJSRA== - dependencies: - "@babel/parser" "^7.16.8" - "@babel/plugin-syntax-import-assertions" "^7.20.0" - "@babel/traverse" "^7.16.8" - "@babel/types" "^7.16.8" - "@graphql-tools/utils" "^9.2.1" - tslib "^2.4.0" - -"@graphql-tools/import@6.7.18": - version "6.7.18" - resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.7.18.tgz#ad092d8a4546bb6ffc3e871e499eec7ac368680b" - integrity sha512-XQDdyZTp+FYmT7as3xRWH/x8dx0QZA2WZqfMF5EWb36a0PiH7WwlRQYIdyYXj8YCLpiWkeBXgBRHmMnwEYR8iQ== - dependencies: - "@graphql-tools/utils" "^9.2.1" - resolve-from "5.0.0" - tslib "^2.4.0" - -"@graphql-tools/json-file-loader@^7.3.7", "@graphql-tools/json-file-loader@^7.4.1": - version "7.4.18" - resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-7.4.18.tgz#d78ae40979bde51cfc59717757354afc9e35fba2" - integrity sha512-AJ1b6Y1wiVgkwsxT5dELXhIVUPs/u3VZ8/0/oOtpcoyO/vAeM5rOvvWegzicOOnQw8G45fgBRMkkRfeuwVt6+w== - dependencies: - "@graphql-tools/utils" "^9.2.1" - globby "^11.0.3" - tslib "^2.4.0" - unixify "^1.0.0" - -"@graphql-tools/load@^7.5.5", "@graphql-tools/load@^7.8.0": - version "7.8.14" - resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-7.8.14.tgz#f2356f9a5f658a42e33934ae036e4b2cadf2d1e9" - integrity sha512-ASQvP+snHMYm+FhIaLxxFgVdRaM0vrN9wW2BKInQpktwWTXVyk+yP5nQUCEGmn0RTdlPKrffBaigxepkEAJPrg== - dependencies: - "@graphql-tools/schema" "^9.0.18" - "@graphql-tools/utils" "^9.2.1" - p-limit "3.1.0" - tslib "^2.4.0" - -"@graphql-tools/merge@^8.2.6", "@graphql-tools/merge@^8.4.1": - version "8.4.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.4.1.tgz#52879e5f73565f504ceea04fcd9ef90a6e733c62" - integrity sha512-hssnPpZ818mxgl5+GfyOOSnnflAxiaTn1A1AojZcIbh4J52sS1Q0gSuBR5VrnUDjuxiqoCotpXdAQl+K+U6KLQ== - dependencies: - "@graphql-tools/utils" "^9.2.1" - tslib "^2.4.0" - -"@graphql-tools/optimize@^1.3.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/optimize/-/optimize-1.4.0.tgz#20d6a9efa185ef8fc4af4fd409963e0907c6e112" - integrity sha512-dJs/2XvZp+wgHH8T5J2TqptT9/6uVzIYvA6uFACha+ufvdMBedkfR4b4GbT8jAKLRARiqRTxy3dctnwkTM2tdw== - dependencies: - tslib "^2.4.0" - -"@graphql-tools/prisma-loader@^7.2.49": - version "7.2.71" - resolved "https://registry.yarnpkg.com/@graphql-tools/prisma-loader/-/prisma-loader-7.2.71.tgz#7540bfabcc9717c10c1ebdb359d265f721205199" - integrity sha512-FuIvhRrkduqPdj3QX0/anCxGViEETfoZ/1NvotfM6iVO1XxR75VXvP/iyKGbK6XvYRXwSstgj2DetlQnqdgXhA== - dependencies: - "@graphql-tools/url-loader" "^7.17.18" - "@graphql-tools/utils" "^9.2.1" - "@types/js-yaml" "^4.0.0" - "@types/json-stable-stringify" "^1.0.32" - "@whatwg-node/fetch" "^0.8.2" - chalk "^4.1.0" - debug "^4.3.1" - dotenv "^16.0.0" - graphql-request "^6.0.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - jose "^4.11.4" - js-yaml "^4.0.0" - json-stable-stringify "^1.0.1" - lodash "^4.17.20" - scuid "^1.1.0" - tslib "^2.4.0" - yaml-ast-parser "^0.0.43" - -"@graphql-tools/relay-operation-optimizer@^6.5.0": - version "6.5.18" - resolved "https://registry.yarnpkg.com/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.5.18.tgz#a1b74a8e0a5d0c795b8a4d19629b654cf66aa5ab" - integrity sha512-mc5VPyTeV+LwiM+DNvoDQfPqwQYhPV/cl5jOBjTgSniyaq8/86aODfMkrE2OduhQ5E00hqrkuL2Fdrgk0w1QJg== - dependencies: - "@ardatan/relay-compiler" "12.0.0" - "@graphql-tools/utils" "^9.2.1" - tslib "^2.4.0" - -"@graphql-tools/schema@^9.0.0", "@graphql-tools/schema@^9.0.18", "@graphql-tools/schema@^9.0.19": - version "9.0.19" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-9.0.19.tgz#c4ad373b5e1b8a0cf365163435b7d236ebdd06e7" - integrity sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w== - dependencies: - "@graphql-tools/merge" "^8.4.1" - "@graphql-tools/utils" "^9.2.1" - tslib "^2.4.0" - value-or-promise "^1.0.12" - -"@graphql-tools/url-loader@^7.13.2", "@graphql-tools/url-loader@^7.17.18", "@graphql-tools/url-loader@^7.9.7": - version "7.17.18" - resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-7.17.18.tgz#3e253594d23483e4c0dd3a4c3dd2ad5cd0141192" - integrity sha512-ear0CiyTj04jCVAxi7TvgbnGDIN2HgqzXzwsfcqiVg9cvjT40NcMlZ2P1lZDgqMkZ9oyLTV8Bw6j+SyG6A+xPw== - dependencies: - "@ardatan/sync-fetch" "^0.0.1" - "@graphql-tools/delegate" "^9.0.31" - "@graphql-tools/executor-graphql-ws" "^0.0.14" - "@graphql-tools/executor-http" "^0.1.7" - "@graphql-tools/executor-legacy-ws" "^0.0.11" - "@graphql-tools/utils" "^9.2.1" - "@graphql-tools/wrap" "^9.4.2" - "@types/ws" "^8.0.0" - "@whatwg-node/fetch" "^0.8.0" - isomorphic-ws "^5.0.0" - tslib "^2.4.0" - value-or-promise "^1.0.11" - ws "^8.12.0" - -"@graphql-tools/utils@^8.8.0": - version "8.13.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.13.1.tgz#b247607e400365c2cd87ff54654d4ad25a7ac491" - integrity sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw== - dependencies: - tslib "^2.4.0" - -"@graphql-tools/utils@^9.0.0", "@graphql-tools/utils@^9.1.1", "@graphql-tools/utils@^9.2.1": - version "9.2.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-9.2.1.tgz#1b3df0ef166cfa3eae706e3518b17d5922721c57" - integrity sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A== - dependencies: - "@graphql-typed-document-node/core" "^3.1.1" - tslib "^2.4.0" - -"@graphql-tools/wrap@^9.4.2": - version "9.4.2" - resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-9.4.2.tgz#30835587c4c73be1780908a7cb077d8013aa2703" - integrity sha512-DFcd9r51lmcEKn0JW43CWkkI2D6T9XI1juW/Yo86i04v43O9w2/k4/nx2XTJv4Yv+iXwUw7Ok81PGltwGJSDSA== - dependencies: - "@graphql-tools/delegate" "^9.0.31" - "@graphql-tools/schema" "^9.0.18" - "@graphql-tools/utils" "^9.2.1" - tslib "^2.4.0" - value-or-promise "^1.0.12" - -"@graphql-typed-document-node/core@3.2.0", "@graphql-typed-document-node/core@^3.1.1", "@graphql-typed-document-node/core@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" - integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== - -"@humanwhocodes/config-array@^0.10.4": - version "0.10.7" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.7.tgz#6d53769fd0c222767e6452e8ebda825c22e9f0dc" - integrity sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/gitignore-to-minimatch@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" - integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" - integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== - dependencies: - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - slash "^3.0.0" - -"@jest/core@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" - integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== - dependencies: - "@jest/console" "^28.1.3" - "@jest/reporters" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^28.1.3" - jest-config "^28.1.3" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-resolve-dependencies "^28.1.3" - jest-runner "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - jest-watcher "^28.1.3" - micromatch "^4.0.4" - pretty-format "^28.1.3" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" - integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== - dependencies: - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - jest-mock "^28.1.3" - -"@jest/expect-utils@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" - integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== - dependencies: - jest-get-type "^28.0.2" - -"@jest/expect@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" - integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== - dependencies: - expect "^28.1.3" - jest-snapshot "^28.1.3" - -"@jest/fake-timers@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" - integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== - dependencies: - "@jest/types" "^28.1.3" - "@sinonjs/fake-timers" "^9.1.2" - "@types/node" "*" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-util "^28.1.3" - -"@jest/globals@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" - integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/types" "^28.1.3" - -"@jest/reporters@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" - integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - jest-worker "^28.1.3" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - terminal-link "^2.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" - integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== - dependencies: - "@sinclair/typebox" "^0.24.1" - -"@jest/source-map@^28.1.2": - version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" - integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== - dependencies: - "@jridgewell/trace-mapping" "^0.3.13" - callsites "^3.0.0" - graceful-fs "^4.2.9" - -"@jest/test-result@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" - integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== - dependencies: - "@jest/console" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" - integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== - dependencies: - "@jest/test-result" "^28.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - slash "^3.0.0" - -"@jest/transform@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" - integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.1" - -"@jest/types@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" - integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== - dependencies: - "@jest/schemas" "^28.1.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@jridgewell/trace-mapping@^0.3.17": - version "0.3.18" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" - integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@jsdevtools/ono@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" - integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== - -"@noble/hashes@1.1.3", "@noble/hashes@~1.1.1": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.3.tgz#360afc77610e0a61f3417e497dcf36862e4f8111" - integrity sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@peculiar/asn1-schema@^2.3.6": - version "2.3.6" - resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz#3dd3c2ade7f702a9a94dfb395c192f5fa5d6b922" - integrity sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA== - dependencies: - asn1js "^3.0.5" - pvtsutils "^1.3.2" - tslib "^2.4.0" - -"@peculiar/json-schema@^1.1.12": - version "1.1.12" - resolved "https://registry.yarnpkg.com/@peculiar/json-schema/-/json-schema-1.1.12.tgz#fe61e85259e3b5ba5ad566cb62ca75b3d3cd5339" - integrity sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w== - dependencies: - tslib "^2.0.0" - -"@peculiar/webcrypto@^1.4.0": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz#078b3e8f598e847b78683dc3ba65feb5029b93a7" - integrity sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A== - dependencies: - "@peculiar/asn1-schema" "^2.3.6" - "@peculiar/json-schema" "^1.1.12" - pvtsutils "^1.3.2" - tslib "^2.5.0" - webcrypto-core "^1.7.7" - -"@repeaterjs/repeater@3.0.4", "@repeaterjs/repeater@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@repeaterjs/repeater/-/repeater-3.0.4.tgz#a04d63f4d1bf5540a41b01a921c9a7fddc3bd1ca" - integrity sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA== - -"@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== - -"@scure/bip39@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" - integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== - dependencies: - "@noble/hashes" "~1.1.1" - "@scure/base" "~1.1.0" - -"@sinclair/typebox@^0.24.1": - version "0.24.51" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" - integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== - -"@sinonjs/commons@^1.7.0": - version "1.8.4" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.4.tgz#d1f2d80f1bd0f2520873f161588bd9b7f8567120" - integrity sha512-RpmQdHVo8hCEHDVpO39zToS9jOhR6nw+/lQAzRNq9ErrGV9IeHM71XCn68svVl/euFeVW6BWX4p35gkhbOcSIQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@types/babel__core@^7.1.14": - version "7.1.19" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" - integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" - integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== - dependencies: - "@babel/types" "^7.3.0" - -"@types/graceful-fs@^4.1.3": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@28.1.8": - version "28.1.8" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-28.1.8.tgz#6936409f3c9724ea431efd412ea0238a0f03b09b" - integrity sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw== - dependencies: - expect "^28.0.0" - pretty-format "^28.0.0" - -"@types/js-yaml@^4.0.0": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138" - integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== - -"@types/json-schema@^7.0.6", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/json-stable-stringify@^1.0.32": - version "1.0.34" - resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz#c0fb25e4d957e0ee2e497c1f553d7f8bb668fd75" - integrity sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/node@*": - version "18.11.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" - integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== - -"@types/node@18.6.2": - version "18.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.2.tgz#ffc5f0f099d27887c8d9067b54e55090fcd54126" - integrity sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/prettier@^2.1.5": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.1.tgz#dfd20e2dc35f027cdd6c1908e80a5ddc7499670e" - integrity sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow== - -"@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== - -"@types/ws@^8.0.0": - version "8.5.4" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5" - integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg== - dependencies: - "@types/node" "*" - -"@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== - -"@types/yargs@^17.0.8": - version "17.0.13" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" - integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.2.tgz#6df092a20e0f9ec748b27f293a12cb39d0c1fe4d" - integrity sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw== - dependencies: - "@typescript-eslint/scope-manager" "5.36.2" - "@typescript-eslint/type-utils" "5.36.2" - "@typescript-eslint/utils" "5.36.2" - debug "^4.3.4" - functional-red-black-tree "^1.0.1" - ignore "^5.2.0" - regexpp "^3.2.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.36.2.tgz#3ddf323d3ac85a25295a55fcb9c7a49ab4680ddd" - integrity sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA== - dependencies: - "@typescript-eslint/scope-manager" "5.36.2" - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/typescript-estree" "5.36.2" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.36.2.tgz#a75eb588a3879ae659514780831370642505d1cd" - integrity sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw== - dependencies: - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/visitor-keys" "5.36.2" - -"@typescript-eslint/type-utils@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.36.2.tgz#752373f4babf05e993adf2cd543a763632826391" - integrity sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw== - dependencies: - "@typescript-eslint/typescript-estree" "5.36.2" - "@typescript-eslint/utils" "5.36.2" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.36.2.tgz#a5066e500ebcfcee36694186ccc57b955c05faf9" - integrity sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ== - -"@typescript-eslint/typescript-estree@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.2.tgz#0c93418b36c53ba0bc34c61fe9405c4d1d8fe560" - integrity sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w== - dependencies: - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/visitor-keys" "5.36.2" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.36.2.tgz#b01a76f0ab244404c7aefc340c5015d5ce6da74c" - integrity sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg== - dependencies: - "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.36.2" - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/typescript-estree" "5.36.2" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/visitor-keys@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.2.tgz#2f8f78da0a3bad3320d2ac24965791ac39dace5a" - integrity sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A== - dependencies: - "@typescript-eslint/types" "5.36.2" - eslint-visitor-keys "^3.3.0" - -"@whatwg-node/events@^0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.0.2.tgz#7b7107268d2982fc7b7aff5ee6803c64018f84dd" - integrity sha512-WKj/lI4QjnLuPrim0cfO7i+HsDSXHxNv1y0CrJhdntuO3hxWZmnXCwNDnwOvry11OjRin6cgWNF+j/9Pn8TN4w== - -"@whatwg-node/events@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.0.3.tgz#13a65dd4f5893f55280f766e29ae48074927acad" - integrity sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA== - -"@whatwg-node/fetch@^0.6.0": - version "0.6.9" - resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.6.9.tgz#6cc694cc0378e27b8dfed427c5bf633eda6972b9" - integrity sha512-JfrBCJdMu9n9OARc0e/hPHcD98/8Nz1CKSdGYDg6VbObDkV/Ys30xe5i/wPOatYbxuvatj1kfWeHf7iNX3i17w== - dependencies: - "@peculiar/webcrypto" "^1.4.0" - "@whatwg-node/node-fetch" "^0.0.5" - busboy "^1.6.0" - urlpattern-polyfill "^6.0.2" - web-streams-polyfill "^3.2.1" - -"@whatwg-node/fetch@^0.8.0", "@whatwg-node/fetch@^0.8.1", "@whatwg-node/fetch@^0.8.2": - version "0.8.8" - resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.8.8.tgz#48c6ad0c6b7951a73e812f09dd22d75e9fa18cae" - integrity sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg== - dependencies: - "@peculiar/webcrypto" "^1.4.0" - "@whatwg-node/node-fetch" "^0.3.6" - busboy "^1.6.0" - urlpattern-polyfill "^8.0.0" - web-streams-polyfill "^3.2.1" - -"@whatwg-node/node-fetch@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@whatwg-node/node-fetch/-/node-fetch-0.0.5.tgz#bebf18891088e5e2fc449dea8d1bc94af5ec38df" - integrity sha512-hbccmaSZaItdsRuBKBEEhLoO+5oXJPxiyd0kG2xXd0Dh3Rt+vZn4pADHxuSiSHLd9CM+S2z4+IxlEGbWUgiz9g== - dependencies: - "@whatwg-node/events" "^0.0.2" - busboy "^1.6.0" - tslib "^2.3.1" - -"@whatwg-node/node-fetch@^0.3.6": - version "0.3.6" - resolved "https://registry.yarnpkg.com/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz#e28816955f359916e2d830b68a64493124faa6d0" - integrity sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA== - dependencies: - "@whatwg-node/events" "^0.0.3" - busboy "^1.6.0" - fast-querystring "^1.1.1" - fast-url-parser "^1.1.3" - tslib "^2.3.1" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.4.1, acorn@^8.8.0: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@^3.0.3, anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-includes@^3.1.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" - integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.flat@^1.2.5: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" - integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-shim-unscopables "^1.0.0" - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - -asn1js@^3.0.1, asn1js@^3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38" - integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ== - dependencies: - pvtsutils "^1.3.2" - pvutils "^1.1.3" - tslib "^2.4.0" - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -auto-bind@~4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" - integrity sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ== - -axios@0.27.2: - version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== - dependencies: - follow-redirects "^1.14.9" - form-data "^4.0.0" - -babel-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" - integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== - dependencies: - "@jest/transform" "^28.1.3" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^28.1.3" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" - integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - -babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: - version "7.0.0-beta.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" - integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-fbjs@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" - integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-member-expression-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-property-literals" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" - -babel-preset-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" - integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== - dependencies: - babel-plugin-jest-hoist "^28.1.3" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.21.3: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== - dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" - -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -bundle-require@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-3.1.2.tgz#1374a7bdcb8b330a7ccc862ccbf7c137cc43ad27" - integrity sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA== - dependencies: - load-tsconfig "^0.2.0" - -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -cac@^6.7.12: - version "6.7.14" - resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" - integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0, camelcase@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001400: - version "1.0.30001430" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001430.tgz#638a8ae00b5a8a97e66ff43733b2701f81b101fa" - integrity sha512-IB1BXTZKPDVPM7cnV4iaKaHxckvdr/3xtctB3f7Hmenx3qYBhGtTZ//7EllK66aKXW98Lx0+7Yr0kxBtIt3tzg== - -capital-case@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" - integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - upper-case-first "^2.0.2" - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -change-case-all@1.0.14: - version "1.0.14" - resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-1.0.14.tgz#bac04da08ad143278d0ac3dda7eccd39280bfba1" - integrity sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA== - dependencies: - change-case "^4.1.2" - is-lower-case "^2.0.2" - is-upper-case "^2.0.2" - lower-case "^2.0.2" - lower-case-first "^2.0.2" - sponge-case "^1.0.1" - swap-case "^2.0.2" - title-case "^3.0.3" - upper-case "^2.0.2" - upper-case-first "^2.0.2" - -change-case-all@1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-1.0.15.tgz#de29393167fc101d646cd76b0ef23e27d09756ad" - integrity sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ== - dependencies: - change-case "^4.1.2" - is-lower-case "^2.0.2" - is-upper-case "^2.0.2" - lower-case "^2.0.2" - lower-case-first "^2.0.2" - sponge-case "^1.0.1" - swap-case "^2.0.2" - title-case "^3.0.3" - upper-case "^2.0.2" - upper-case-first "^2.0.2" - -change-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" - integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== - dependencies: - camel-case "^4.1.2" - capital-case "^1.0.4" - constant-case "^3.0.4" - dot-case "^3.0.4" - header-case "^2.0.4" - no-case "^3.0.4" - param-case "^3.0.4" - pascal-case "^3.1.2" - path-case "^3.0.4" - sentence-case "^3.0.4" - snake-case "^3.0.4" - tslib "^2.0.3" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chokidar@^3.5.1, chokidar@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -ci-info@^3.2.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f" - integrity sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw== - -cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@^2.5.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.8.0.tgz#e97a3e2bd00e6d85aa0c13d7f9e3ce236f7787fc" - integrity sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ== - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colorette@^2.0.16: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - -commander@^9.3.0: - version "9.4.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" - integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== - -common-tags@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" - integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -confusing-browser-globals@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" - integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== - -constant-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1" - integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - upper-case "^2.0.2" - -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -cosmiconfig-typescript-loader@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz#c4259ce474c9df0f32274ed162c0447c951ef073" - integrity sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q== - -cosmiconfig@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.0.0.tgz#e9feae014eab580f858f8a0288f38997a7bebe97" - integrity sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ== - dependencies: - import-fresh "^3.2.1" - js-yaml "^4.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - -cosmiconfig@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-fetch@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== - dependencies: - node-fetch "2.6.7" - -cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -dataloader@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.2.2.tgz#216dc509b5abe39d43a9b9d97e6e5e473dfbe3e0" - integrity sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g== - -debounce@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" - integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== - -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== - -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -dependency-graph@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" - integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== - -detect-indent@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" - integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -diff-sequences@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" - integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -dotenv@16.0.2: - version "16.0.2" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.2.tgz#0b0f8652c016a3858ef795024508cddc4bffc5bf" - integrity sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA== - -dotenv@^16.0.0: - version "16.0.3" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== - -dset@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.2.tgz#89c436ca6450398396dc6538ea00abc0c54cd45a" - integrity sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q== - -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== - -emittery@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" - integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -enhanced-resolve@^5.0.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5, es-abstract@^1.20.4: - version "1.20.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861" - integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -esbuild-android-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz#5f25864055dbd62e250f360b38b4c382224063af" - integrity sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g== - -esbuild-android-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz#d8820f999314efbe8e0f050653a99ff2da632b0f" - integrity sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w== - -esbuild-darwin-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz#99ae7fdaa43947b06cd9d1a1c3c2c9f245d81fd0" - integrity sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg== - -esbuild-darwin-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz#bafa1814354ad1a47adcad73de416130ef7f55e3" - integrity sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A== - -esbuild-freebsd-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz#84ef85535c5cc38b627d1c5115623b088d1de161" - integrity sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA== - -esbuild-freebsd-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz#033f21de434ec8e0c478054b119af8056763c2d8" - integrity sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q== - -esbuild-linux-32@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz#54290ea8035cba0faf1791ce9ae6693005512535" - integrity sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w== - -esbuild-linux-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz#4264249281ea388ead948614b57fb1ddf7779a2c" - integrity sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A== - -esbuild-linux-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz#9323c333924f97a02bdd2ae8912b36298acb312d" - integrity sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ== - -esbuild-linux-arm@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz#b407f47b3ae721fe4e00e19e9f19289bef87a111" - integrity sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ== - -esbuild-linux-mips64le@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz#bdf905aae5c0bcaa8f83567fe4c4c1bdc1f14447" - integrity sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A== - -esbuild-linux-ppc64le@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz#2911eae1c90ff58a3bd3259cb557235df25aa3b4" - integrity sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA== - -esbuild-linux-riscv64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz#1837c660be12b1d20d2a29c7189ea703f93e9265" - integrity sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow== - -esbuild-linux-s390x@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz#d52880ece229d1bd10b2d936b792914ffb07c7fc" - integrity sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag== - -esbuild-netbsd-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz#de14da46f1d20352b43e15d97a80a8788275e6ed" - integrity sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ== - -esbuild-openbsd-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz#45e8a5fd74d92ad8f732c43582369c7990f5a0ac" - integrity sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w== - -esbuild-sunos-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz#f646ac3da7aac521ee0fdbc192750c87da697806" - integrity sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw== - -esbuild-windows-32@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz#fb4fe77c7591418880b3c9b5900adc4c094f2401" - integrity sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA== - -esbuild-windows-64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz#1fca8c654392c0c31bdaaed168becfea80e20660" - integrity sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ== - -esbuild-windows-arm64@0.15.13: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz#4ffd01b6b2888603f1584a2fe96b1f6a6f2b3dd8" - integrity sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg== - -esbuild@^0.15.1: - version "0.15.13" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.13.tgz#7293480038feb2bafa91d3f6a20edab3ba6c108a" - integrity sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ== - optionalDependencies: - "@esbuild/android-arm" "0.15.13" - "@esbuild/linux-loong64" "0.15.13" - esbuild-android-64 "0.15.13" - esbuild-android-arm64 "0.15.13" - esbuild-darwin-64 "0.15.13" - esbuild-darwin-arm64 "0.15.13" - esbuild-freebsd-64 "0.15.13" - esbuild-freebsd-arm64 "0.15.13" - esbuild-linux-32 "0.15.13" - esbuild-linux-64 "0.15.13" - esbuild-linux-arm "0.15.13" - esbuild-linux-arm64 "0.15.13" - esbuild-linux-mips64le "0.15.13" - esbuild-linux-ppc64le "0.15.13" - esbuild-linux-riscv64 "0.15.13" - esbuild-linux-s390x "0.15.13" - esbuild-netbsd-64 "0.15.13" - esbuild-openbsd-64 "0.15.13" - esbuild-sunos-64 "0.15.13" - esbuild-windows-32 "0.15.13" - esbuild-windows-64 "0.15.13" - esbuild-windows-arm64 "0.15.13" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-config-airbnb-base@15.0.0, eslint-config-airbnb-base@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" - integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.5" - semver "^6.3.0" - -eslint-config-airbnb-typescript@17.0.0: - version "17.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.0.0.tgz#360dbcf810b26bbcf2ff716198465775f1c49a07" - integrity sha512-elNiuzD0kPAPTXjFWg+lE24nMdHMtuxgYoD30OyMD6yrW1AhFZPAg27VX7d3tzOErw+dgJTNWfRSDqEcXb4V0g== - dependencies: - eslint-config-airbnb-base "^15.0.0" - -eslint-config-prettier@8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" - integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@2.26.0: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== - dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" - has "^1.0.3" - is-core-module "^2.8.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint@8.23.0: - version "8.23.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040" - integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA== - dependencies: - "@eslint/eslintrc" "^1.3.1" - "@humanwhocodes/config-array" "^0.10.4" - "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" - "@humanwhocodes/module-importer" "^1.0.1" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.4.0" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.15.0" - globby "^11.1.0" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.4.0: - version "9.4.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" - integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expect@^28.0.0, expect@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" - integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== - dependencies: - "@jest/expect-utils" "^28.1.3" - jest-get-type "^28.0.2" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extract-files@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-11.0.0.tgz#b72d428712f787eef1f5193aff8ab5351ca8469a" - integrity sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ== - -extract-files@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a" - integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ== - -fast-decode-uri-component@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" - integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fast-querystring@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fast-querystring/-/fast-querystring-1.1.1.tgz#f4c56ef56b1a954880cfd8c01b83f9e1a3d3fda2" - integrity sha512-qR2r+e3HvhEFmpdHMv//U8FnFlnYjaC6QKDuaXALDkw2kvHO8WDjxH+f/rHGR4Me4pnk8p9JAkRNTjYHAKRn2Q== - dependencies: - fast-decode-uri-component "^1.0.1" - -fast-url-parser@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" - integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== - dependencies: - punycode "^1.3.2" - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - -fbjs-css-vars@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" - integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== - -fbjs@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.4.tgz#e1871c6bd3083bac71ff2da868ad5067d37716c6" - integrity sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ== - dependencies: - cross-fetch "^3.1.5" - fbjs-css-vars "^1.0.0" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.30" - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -follow-redirects@^1.14.9: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -form-data@4.0.0, form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.1, glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.15.0: - version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== - dependencies: - type-fest "^0.20.2" - -globby@^11.0.3, globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -graphql-config@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-4.5.0.tgz#257c2338950b8dce295a27f75c5f6c39f8f777b2" - integrity sha512-x6D0/cftpLUJ0Ch1e5sj1TZn6Wcxx4oMfmhaG9shM0DKajA9iR+j1z86GSTQ19fShbGvrSSvbIQsHku6aQ6BBw== - dependencies: - "@graphql-tools/graphql-file-loader" "^7.3.7" - "@graphql-tools/json-file-loader" "^7.3.7" - "@graphql-tools/load" "^7.5.5" - "@graphql-tools/merge" "^8.2.6" - "@graphql-tools/url-loader" "^7.9.7" - "@graphql-tools/utils" "^9.0.0" - cosmiconfig "8.0.0" - jiti "1.17.1" - minimatch "4.2.3" - string-env-interpolation "1.0.1" - tslib "^2.4.0" - -graphql-request@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-5.2.0.tgz#a05fb54a517d91bb2d7aefa17ade4523dc5ebdca" - integrity sha512-pLhKIvnMyBERL0dtFI3medKqWOz/RhHdcgbZ+hMMIb32mEPa5MJSzS4AuXxfI4sRAu6JVVk5tvXuGfCWl9JYWQ== - dependencies: - "@graphql-typed-document-node/core" "^3.1.1" - cross-fetch "^3.1.5" - extract-files "^9.0.0" - form-data "^3.0.0" - -graphql-request@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-6.0.0.tgz#9c8b6a0c341f289e049936d03cc9205300faae1c" - integrity sha512-2BmHTuglonjZvmNVw6ZzCfFlW/qkIPds0f+Qdi/Lvjsl3whJg2uvHmSvHnLWhUTEw6zcxPYAHiZoPvSVKOZ7Jw== - dependencies: - "@graphql-typed-document-node/core" "^3.2.0" - cross-fetch "^3.1.5" - -graphql-tag@^2.11.0: - version "2.12.6" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" - integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== - dependencies: - tslib "^2.1.0" - -graphql-ws@5.12.1: - version "5.12.1" - resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.12.1.tgz#c62d5ac54dbd409cc6520b0b39de374b3d59d0dd" - integrity sha512-umt4f5NnMK46ChM2coO36PTFhHouBrK9stWWBczERguwYrGnPNxJ9dimU6IyOBfOkC6Izhkg4H8+F51W/8CYDg== - -graphql@^16.5.0: - version "16.6.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" - integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== - -handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -header-case@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063" - integrity sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q== - dependencies: - capital-case "^1.0.4" - tslib "^2.0.3" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -immutable@~3.7.6: - version "3.7.6" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" - integrity sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-from@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-4.0.0.tgz#2710b8d66817d232e16f4166e319248d3d5492e2" - integrity sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ== - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inquirer@^8.0.0: - version "8.2.5" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" - integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^7.0.0" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -is-absolute@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" - integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== - dependencies: - is-relative "^1.0.0" - is-windows "^1.0.1" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-glob@4.0.3, is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - -is-lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-2.0.2.tgz#1c0884d3012c841556243483aa5d522f47396d2a" - integrity sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ== - dependencies: - tslib "^2.0.3" - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-relative@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" - integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== - dependencies: - is-unc-path "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-unc-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" - integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== - dependencies: - unc-path-regex "^0.1.2" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-upper-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-2.0.2.tgz#f1105ced1fe4de906a5f39553e7d3803fd804649" - integrity sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ== - dependencies: - tslib "^2.0.3" - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-windows@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isomorphic-ws@5.0.0, isomorphic-ws@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" - integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jest-changed-files@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" - integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== - dependencies: - execa "^5.0.0" - p-limit "^3.1.0" - -jest-circus@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" - integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - is-generator-fn "^2.0.0" - jest-each "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - p-limit "^3.1.0" - pretty-format "^28.1.3" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-cli@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" - integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== - dependencies: - "@jest/core" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - prompts "^2.0.1" - yargs "^17.3.1" - -jest-config@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" - integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^28.1.3" - "@jest/types" "^28.1.3" - babel-jest "^28.1.3" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^28.1.3" - jest-environment-node "^28.1.3" - jest-get-type "^28.0.2" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-runner "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^28.1.3" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" - integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== - dependencies: - chalk "^4.0.0" - diff-sequences "^28.1.1" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - -jest-docblock@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" - integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== - dependencies: - detect-newline "^3.0.0" - -jest-each@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" - integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== - dependencies: - "@jest/types" "^28.1.3" - chalk "^4.0.0" - jest-get-type "^28.0.2" - jest-util "^28.1.3" - pretty-format "^28.1.3" - -jest-environment-node@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" - integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - jest-mock "^28.1.3" - jest-util "^28.1.3" - -jest-get-type@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" - integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== - -jest-haste-map@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" - integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== - dependencies: - "@jest/types" "^28.1.3" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" - jest-worker "^28.1.3" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - -jest-leak-detector@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" - integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== - dependencies: - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - -jest-matcher-utils@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" - integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== - dependencies: - chalk "^4.0.0" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - -jest-message-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" - integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^28.1.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^28.1.3" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" - integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== - dependencies: - "@jest/types" "^28.1.3" - "@types/node" "*" - -jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== - -jest-regex-util@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" - integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== - -jest-resolve-dependencies@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" - integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== - dependencies: - jest-regex-util "^28.0.2" - jest-snapshot "^28.1.3" - -jest-resolve@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" - integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-pnp-resolver "^1.2.2" - jest-util "^28.1.3" - jest-validate "^28.1.3" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - -jest-runner@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" - integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== - dependencies: - "@jest/console" "^28.1.3" - "@jest/environment" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.10.2" - graceful-fs "^4.2.9" - jest-docblock "^28.1.1" - jest-environment-node "^28.1.3" - jest-haste-map "^28.1.3" - jest-leak-detector "^28.1.3" - jest-message-util "^28.1.3" - jest-resolve "^28.1.3" - jest-runtime "^28.1.3" - jest-util "^28.1.3" - jest-watcher "^28.1.3" - jest-worker "^28.1.3" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" - integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/globals" "^28.1.3" - "@jest/source-map" "^28.1.2" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-snapshot@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" - integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/babel__traverse" "^7.0.6" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^28.1.3" - graceful-fs "^4.2.9" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - jest-haste-map "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - natural-compare "^1.4.0" - pretty-format "^28.1.3" - semver "^7.3.5" - -jest-util@^28.0.0, jest-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" - integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== - dependencies: - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" - integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== - dependencies: - "@jest/types" "^28.1.3" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^28.0.2" - leven "^3.1.0" - pretty-format "^28.1.3" - -jest-watcher@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" - integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== - dependencies: - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.10.2" - jest-util "^28.1.3" - string-length "^4.0.1" - -jest-worker@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" - integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" - integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== - dependencies: - "@jest/core" "^28.1.3" - "@jest/types" "^28.1.3" - import-local "^3.0.2" - jest-cli "^28.1.3" - -jiti@1.17.1: - version "1.17.1" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.17.1.tgz#264daa43ee89a03e8be28c3d712ccc4eb9f1e8ed" - integrity sha512-NZIITw8uZQFuzQimqjUxIrIcEdxYDFIe/0xYfIlVXTkiBjjyBEvgasj5bb0/cHtPRD/NziPbT312sFrkI5ALpw== - -jose@^4.11.4: - version "4.14.2" - resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.2.tgz#f126e2805555882f0d86d1f84bcf00481d5ab3bf" - integrity sha512-Fcbi5lskAiSvs8qhdQBusANZWwyATdp7IxgHJTXiaU74sbVjX9uAw+myDPvI8pNo2wXKHECXCR63hqhRkN/SSQ== - -joycon@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" - integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^4.0.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-ref-parser@^9.0.9: - version "9.0.9" - resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#66ea538e7450b12af342fa3d5b8458bc1e1e013f" - integrity sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q== - dependencies: - "@apidevtools/json-schema-ref-parser" "9.0.9" - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json-stable-stringify@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz#e06f23128e0bbe342dc996ed5a19e28b57b580e0" - integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== - dependencies: - jsonify "^0.0.1" - -json-to-pretty-yaml@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz#f4cd0bd0a5e8fe1df25aaf5ba118b099fd992d5b" - integrity sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A== - dependencies: - remedial "^1.0.7" - remove-trailing-spaces "^1.0.6" - -json5@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonc-parser@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" - integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lilconfig@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -listr2@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-4.0.5.tgz#9dcc50221583e8b4c71c43f9c7dfd0ef546b75d5" - integrity sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.16" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.5.5" - through "^2.3.8" - wrap-ansi "^7.0.0" - -load-tsconfig@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/load-tsconfig/-/load-tsconfig-0.2.3.tgz#08af3e7744943caab0c75f8af7f1703639c3ef1f" - integrity sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== - -lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@^4.0.0, log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case-first@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-2.0.2.tgz#64c2324a2250bf7c37c5901e76a5b5309301160b" - integrity sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg== - dependencies: - tslib "^2.0.3" - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" - integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@1.x, make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -map-cache@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - -marked@^4.2.5: - version "4.2.5" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.2.5.tgz#979813dfc1252cc123a79b71b095759a32f42a5d" - integrity sha512-jPueVhumq7idETHkb203WDD4fMA3yV9emQ5vLwop58lu8bTclMghBWcYAavlDqIEMaisADinV1TooIFCfqOsYQ== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -meros@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/meros/-/meros-1.2.1.tgz#056f7a76e8571d0aaf3c7afcbe7eb6407ff7329e" - integrity sha512-R2f/jxYqCAGI19KhAvaxSOxALBMkaXWH2a7rOyqQw+ZmizX5bKkEYWLzdhC+U82ZVVPVp6MCXe3EkVligh+12g== - -micromatch@^4.0.0, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.3.tgz#b4dcece1d674dee104bb0fb833ebb85a78cbbca6" - integrity sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff" - integrity sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.1: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== - dependencies: - whatwg-url "^5.0.0" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -nullthrows@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" - integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -"openapi-typescript-codegen@https://github.com/aptos-labs/openapi-typescript-codegen/releases/download/v0.24.0-p1/openapi-typescript-codegen-v0.24.0-p1.tgz": - version "0.24.0" - resolved "https://github.com/aptos-labs/openapi-typescript-codegen/releases/download/v0.24.0-p1/openapi-typescript-codegen-v0.24.0-p1.tgz#36a66aa2dc0d02ffc75b87c0b16fac12f273a42a" - dependencies: - camelcase "^6.3.0" - commander "^9.3.0" - fs-extra "^10.1.0" - handlebars "^4.7.7" - json-schema-ref-parser "^9.0.9" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -p-limit@3.1.0, p-limit@^3.0.2, p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-filepath@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" - integrity sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q== - dependencies: - is-absolute "^1.0.0" - map-cache "^0.2.0" - path-root "^0.1.1" - -parse-json@^5.0.0, parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -path-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.4.tgz#9168645334eb942658375c56f80b4c0cb5f82c6f" - integrity sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-root-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" - integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ== - -path-root@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" - integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg== - dependencies: - path-root-regex "^0.1.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pirates@^4.0.1, pirates@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -postcss-load-config@^3.0.1: - version "3.1.4" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" - integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== - dependencies: - lilconfig "^2.0.5" - yaml "^1.10.2" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" - integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== - -pretty-format@^28.0.0, pretty-format@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" - integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== - dependencies: - "@jest/schemas" "^28.1.3" - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -punycode@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -pvtsutils@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.2.tgz#9f8570d132cdd3c27ab7d51a2799239bf8d8d5de" - integrity sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ== - dependencies: - tslib "^2.4.0" - -pvutils@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" - integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -readable-stream@^3.4.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -relay-runtime@12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-12.0.0.tgz#1e039282bdb5e0c1b9a7dc7f6b9a09d4f4ff8237" - integrity sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug== - dependencies: - "@babel/runtime" "^7.0.0" - fbjs "^3.0.0" - invariant "^2.2.4" - -remedial@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/remedial/-/remedial-1.0.8.tgz#a5e4fd52a0e4956adbaf62da63a5a46a78c578a0" - integrity sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg== - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== - -remove-trailing-spaces@^1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz#4354d22f3236374702f58ee373168f6d6887ada7" - integrity sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@5.0.0, resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== - -resolve@^1.20.0, resolve@^1.22.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rollup@^2.74.1: - version "2.79.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" - integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== - optionalDependencies: - fsevents "~2.3.2" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rxjs@^7.5.5: - version "7.8.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== - dependencies: - tslib "^2.1.0" - -safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -scuid@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/scuid/-/scuid-1.1.0.tgz#d3f9f920956e737a60f72d0e4ad280bf324d5dab" - integrity sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg== - -semver@7.x, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -sentence-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f" - integrity sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - upper-case-first "^2.0.2" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shell-quote@^1.7.3: - version "1.8.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" - integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== - -shiki@^0.12.1: - version "0.12.1" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.12.1.tgz#26fce51da12d055f479a091a5307470786f300cd" - integrity sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ== - dependencies: - jsonc-parser "^3.2.0" - vscode-oniguruma "^1.7.0" - vscode-textmate "^8.0.0" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signedsource@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/signedsource/-/signedsource-1.0.0.tgz#1ddace4981798f93bd833973803d80d52e93ad6a" - integrity sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww== - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -snake-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" - integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@0.8.0-beta.0: - version "0.8.0-beta.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" - integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== - dependencies: - whatwg-url "^7.0.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sponge-case@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sponge-case/-/sponge-case-1.0.1.tgz#260833b86453883d974f84854cdb63aecc5aef4c" - integrity sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA== - dependencies: - tslib "^2.0.3" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== - dependencies: - escape-string-regexp "^2.0.0" - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string-env-interpolation@1.0.1, string-env-interpolation@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" - integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg== - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -sucrase@^3.20.3: - version "3.28.0" - resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.28.0.tgz#7fd8b3118d2155fcdf291088ab77fa6eefd63c4c" - integrity sha512-TK9600YInjuiIhVM3729rH4ZKPOsGeyXUwY+Ugu9eilNbdTFyHr6XcAGYbRVZPDgWj6tgI7bx95aaJjHnbffag== - dependencies: - commander "^4.0.0" - glob "7.1.6" - lines-and-columns "^1.1.6" - mz "^2.7.0" - pirates "^4.0.1" - ts-interface-checker "^0.1.9" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" - integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -swap-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-2.0.2.tgz#671aedb3c9c137e2985ef51c51f9e98445bf70d9" - integrity sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw== - dependencies: - tslib "^2.0.3" - -tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -through@^2.3.6, through@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -title-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/title-case/-/title-case-3.0.3.tgz#bc689b46f02e411f1d1e1d081f7c3deca0489982" - integrity sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA== - dependencies: - tslib "^2.0.3" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== - dependencies: - punycode "^2.1.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -tree-kill@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" - integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== - -ts-interface-checker@^0.1.9: - version "0.1.13" - resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" - integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== - -ts-jest@28.0.8: - version "28.0.8" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-28.0.8.tgz#cd204b8e7a2f78da32cf6c95c9a6165c5b99cc73" - integrity sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^28.0.0" - json5 "^2.2.1" - lodash.memoize "4.x" - make-error "1.x" - semver "7.x" - yargs-parser "^21.0.1" - -ts-loader@9.3.1: - version "9.3.1" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.3.1.tgz#fe25cca56e3e71c1087fe48dc67f4df8c59b22d4" - integrity sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.0.0" - micromatch "^4.0.0" - semver "^7.3.4" - -ts-log@^2.2.3: - version "2.2.5" - resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.5.tgz#aef3252f1143d11047e2cb6f7cfaac7408d96623" - integrity sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA== - -ts-node@10.9.1, ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== - -tslib@~2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" - integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== - -tsup@6.2.3: - version "6.2.3" - resolved "https://registry.yarnpkg.com/tsup/-/tsup-6.2.3.tgz#87f57b2e53d49f1c1ab89aba21fed96aaab0ec9f" - integrity sha512-J5Pu2Dx0E1wlpIEsVFv9ryzP1pZ1OYsJ2cBHZ7GrKteytNdzaSz5hmLX7/nAxtypq+jVkVvA79d7S83ETgHQ5w== - dependencies: - bundle-require "^3.1.0" - cac "^6.7.12" - chokidar "^3.5.1" - debug "^4.3.1" - esbuild "^0.15.1" - execa "^5.0.0" - globby "^11.0.3" - joycon "^3.0.1" - postcss-load-config "^3.0.1" - resolve-from "^5.0.0" - rollup "^2.74.1" - source-map "0.8.0-beta.0" - sucrase "^3.20.3" - tree-kill "^1.2.2" - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tweetnacl@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -typedoc@^0.23.20: - version "0.23.24" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.24.tgz#01cf32c09f2c19362e72a9ce1552d6e5b48c4fef" - integrity sha512-bfmy8lNQh+WrPYcJbtjQ6JEEsVl/ce1ZIXyXhyW+a1vFrjO39t6J8sL/d6FfAGrJTc7McCXgk9AanYBSNvLdIA== - dependencies: - lunr "^2.3.9" - marked "^4.2.5" - minimatch "^5.1.2" - shiki "^0.12.1" - -typescript@4.8.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790" - integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw== - -ua-parser-js@^0.7.30: - version "0.7.35" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.35.tgz#8bda4827be4f0b1dda91699a29499575a1f1d307" - integrity sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g== - -uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -unc-path-regex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" - integrity sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unixify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" - integrity sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg== - dependencies: - normalize-path "^2.1.1" - -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -upper-case-first@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" - integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg== - dependencies: - tslib "^2.0.3" - -upper-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.2.tgz#d89810823faab1df1549b7d97a76f8662bae6f7a" - integrity sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg== - dependencies: - tslib "^2.0.3" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -urlpattern-polyfill@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-6.0.2.tgz#a193fe773459865a2a5c93b246bb794b13d07256" - integrity sha512-5vZjFlH9ofROmuWmXM9yj2wljYKgWstGwe8YTyiqM7hVum/g9LyCizPZtb3UqsuppVwety9QJmfc42VggLpTgg== - dependencies: - braces "^3.0.2" - -urlpattern-polyfill@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz#99f096e35eff8bf4b5a2aa7d58a1523d6ebc7ce5" - integrity sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ== - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -v8-to-istanbul@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" - integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - -value-or-promise@^1.0.11, value-or-promise@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.12.tgz#0e5abfeec70148c78460a849f6b003ea7986f15c" - integrity sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q== - -vscode-oniguruma@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - -vscode-textmate@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== - -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - -web-streams-polyfill@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" - integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== - -webcrypto-core@^1.7.7: - version "1.7.7" - resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.7.tgz#06f24b3498463e570fed64d7cab149e5437b162c" - integrity sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g== - dependencies: - "@peculiar/asn1-schema" "^2.3.6" - "@peculiar/json-schema" "^1.1.12" - asn1js "^3.0.1" - pvtsutils "^1.3.2" - tslib "^2.4.0" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" - integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -ws@8.13.0, ws@^8.12.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml-ast-parser@^0.0.43: - version "0.0.43" - resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" - integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== - -yaml@^1.10.0, yaml@^1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@^18.1.2: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^21.0.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs@^15.3.1: - version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" - integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - -yargs@^17.0.0: - version "17.7.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" - integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yargs@^17.3.1: - version "17.6.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" - integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/m1/genesis/movementLocal b/m1/genesis/movementLocal new file mode 100644 index 000000000..b6fc4c620 --- /dev/null +++ b/m1/genesis/movementLocal @@ -0,0 +1 @@ +hello \ No newline at end of file diff --git a/m1/scripts/anr.sh b/m1/scripts/anr.sh index e3482af12..c4973d0af 100755 --- a/m1/scripts/anr.sh +++ b/m1/scripts/anr.sh @@ -14,7 +14,11 @@ export SUBNET_ID=srEXiWaHZNDcVtfHLb38cFiwKVLJ8xnhDF5qpWbYdowxEiyid echo $SUBNET_ID # Copy the subnet binary to the plugin dir +<<<<<<< HEAD # cp ./target/debug/subnet ${AVALANCHEGO_PLUGIN_PATH}/${SUBNET_ID} +======= +cp ./target/debug/subnet ${AVALANCHEGO_PLUGIN_PATH}/${SUBNET_ID} +>>>>>>> indexer-fix # cp ./target/debug/subnet ${AVALANCHEGO_PLUGIN_PATH}/subnet # Start the avalanche-network-runner diff --git a/m1/scripts/build.debug.sh b/m1/scripts/build.debug.sh new file mode 100755 index 000000000..024d11299 --- /dev/null +++ b/m1/scripts/build.debug.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -xue + +if ! [[ "$0" =~ scripts/build.debug.sh ]]; then + echo "must be run from m1" + exit 255 +fi + +PROTOC_VERSION=$(protoc --version | cut -f2 -d' ') +if [[ "${PROTOC_VERSION}" == "" ]] || [[ "${PROTOC_VERSION}" < 3.15.0 ]]; then + echo "protoc must be installed and the version must be greater than 3.15.0" + exit 255 +fi + +# "--bin" can be specified multiple times for each directory in "bin/*" or workspaces +cargo build -p subnet --bin subnet + +./target/debug/subnet --help + +./target/debug/subnet genesis "hello world" +./target/debug/subnet vm-id timestampvm \ No newline at end of file diff --git a/m1/scripts/build.release.sh b/m1/scripts/build.release.sh new file mode 100755 index 000000000..7d596856f --- /dev/null +++ b/m1/scripts/build.release.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -xue + +if ! [[ "$0" =~ scripts/build.release.sh ]]; then + echo "must be run from repository root" + exit 255 +fi + +PROTOC_VERSION=$(protoc --version | cut -f2 -d' ') +if [[ "${PROTOC_VERSION}" == "" ]] || [[ "${PROTOC_VERSION}" < 3.15.0 ]]; then + echo "protoc must be installed and the version must be greater than 3.15.0" + exit 255 +fi + +# "--bin" can be specified multiple times for each directory in "bin/*" or workspaces +cargo build -p subnet \ +--release \ +--bin subnet + +./target/release/subnet --help + +./target/release/subnet genesis "hello world" +./target/release/subnet vm-id timestampvm diff --git a/m1/scripts/fuji.sh b/m1/scripts/fuji.sh new file mode 100755 index 000000000..86d9b9538 --- /dev/null +++ b/m1/scripts/fuji.sh @@ -0,0 +1,7 @@ +VM_NAME="movement" +VM_ID="b6z34iYog6Qm8uUWmssHYWDhShhufDBtLo75K9nHwU69GTs8o" +SUBNET_ID="K4GygGTpKkNzzjiLfZVsmQduGqSFztJx4nk52CvA1afcFAhsH" + +cargo build -p subnet +cp ./target/debug/subnet ~/.avalanchego/plugins/$VM_ID +./avalanchego --http-host=0.0.0.0 --network-id="fuji" --track-subnets "$SUBNET_ID" \ No newline at end of file diff --git a/m1/scripts/run.debug.sh b/m1/scripts/run.debug.sh new file mode 100755 index 000000000..129663a69 --- /dev/null +++ b/m1/scripts/run.debug.sh @@ -0,0 +1,8 @@ +#!/bin/bash -e + +if ! [[ "$0" =~ scripts/run.debug.sh ]]; then + echo "must be run from the m1 directory" + exit 255 +fi + +SUBNET_TIMEOUT=300000 ./scripts/tests.debug.sh \ No newline at end of file diff --git a/m1/scripts/start-subnet.sh b/m1/scripts/start-subnet.sh index e17dafd8b..64808a239 100755 --- a/m1/scripts/start-subnet.sh +++ b/m1/scripts/start-subnet.sh @@ -7,7 +7,11 @@ echo hello > /tmp/subnet.genesis.json avalanche-network-runner control start \ --log-level debug \ --endpoint="0.0.0.0:8080" \ +<<<<<<< HEAD --avalanchego-path="${AVALANCHEGO_EXEC_PATH}" +======= +--avalanchego-path="${AVALANCHEGO_EXEC_PATH}" \ +>>>>>>> indexer-fix --blockchain-specs '[{"vm_name":"subnet","genesis":"/tmp/subnet.genesis.json","blockchain_alias":"movement"}]' \ # avalanche-network-runner control create-blockchains '[{"vm_name":"movement", "subnet_id": "srEXiWaHZNDcVtfHLb38cFiwKVLJ8xnhDF5qpWbYdowxEiyid"}]' \ diff --git a/m1/scripts/tests.debug.sh b/m1/scripts/tests.debug.sh new file mode 100755 index 000000000..645bf2fed --- /dev/null +++ b/m1/scripts/tests.debug.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e + +if ! [[ "$0" =~ scripts/tests.debug.sh ]]; then + echo "must be run from the m1 directory" + exit 255 +fi + +./scripts/build.debug.sh \ +&& VM_PLUGIN_PATH=$(pwd)/target/debug/subnet \ +./scripts/tests.e2e.sh \ No newline at end of file diff --git a/m1/scripts/tests.e2e.sh b/m1/scripts/tests.e2e.sh new file mode 100755 index 000000000..73b614048 --- /dev/null +++ b/m1/scripts/tests.e2e.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +set -e + +# build timestampvm binary +# ./scripts/build.release.sh +# +# download from github, keep network running +# VM_PLUGIN_PATH=$(pwd)/target/release/timestampvm ./scripts/tests.e2e.sh +# +# download from github, shut down network +# NETWORK_RUNNER_ENABLE_SHUTDOWN=1 VM_PLUGIN_PATH=$(pwd)/target/release/timestampvm ./scripts/tests.e2e.sh +# +# use custom avalanchego binary +# VM_PLUGIN_PATH=$(pwd)/target/release/timestampvm ./scripts/tests.e2e.sh ~/go/src/github.com/ava-labs/avalanchego/build/avalanchego +# +if ! [[ "$0" =~ scripts/tests.e2e.sh ]]; then + echo "must be run from repository root" + exit 255 +fi + +AVALANCHEGO_PATH=${1:-""} +echo AVALANCHEGO_PATH: ${AVALANCHEGO_PATH} +echo VM_PLUGIN_PATH: ${VM_PLUGIN_PATH} + +################################# +# download avalanche-network-runner +# https://github.com/ava-labs/avalanche-network-runner +# TODO: use "go install -v github.com/ava-labs/avalanche-network-runner/cmd/avalanche-network-runner@v${NETWORK_RUNNER_VERSION}" +GOOS=$(go env GOOS) +NETWORK_RUNNER_VERSION=1.7.1 +DOWNLOAD_PATH=/tmp/avalanche-network-runner.tar.gz +DOWNLOAD_URL=https://github.com/ava-labs/avalanche-network-runner/releases/download/v${NETWORK_RUNNER_VERSION}/avalanche-network-runner_${NETWORK_RUNNER_VERSION}_linux_amd64.tar.gz +if [[ ${GOOS} == "darwin" ]]; then + DOWNLOAD_URL=https://github.com/ava-labs/avalanche-network-runner/releases/download/v${NETWORK_RUNNER_VERSION}/avalanche-network-runner_${NETWORK_RUNNER_VERSION}_darwin_amd64.tar.gz +fi +echo ${DOWNLOAD_URL} + +rm -f ${DOWNLOAD_PATH} +rm -f /tmp/avalanche-network-runner + +echo "downloading avalanche-network-runner ${NETWORK_RUNNER_VERSION} at ${DOWNLOAD_URL}" +curl -L ${DOWNLOAD_URL} -o ${DOWNLOAD_PATH} + +echo "extracting downloaded avalanche-network-runner" +tar xzvf ${DOWNLOAD_PATH} -C /tmp +/tmp/avalanche-network-runner -h + +################################# +# run "avalanche-network-runner" server +echo "launch avalanche-network-runner in the background" +/tmp/avalanche-network-runner \ +server \ +--log-level debug \ +--port=":12342" \ +--disable-grpc-gateway & +NETWORK_RUNNER_PID=${!} +sleep 5 + +################################# +echo "running e2e tests" +NETWORK_RUNNER_GRPC_ENDPOINT=http://127.0.0.1:12342 \ +AVALANCHEGO_PATH=${AVALANCHEGO_PATH} \ +VM_PLUGIN_PATH=${VM_PLUGIN_PATH} \ +RUST_LOG=debug \ +cargo test --all-features --package e2e -- --show-output --nocapture + +################################# +echo "" +echo "" +if [ -z "$NETWORK_RUNNER_ENABLE_SHUTDOWN" ] +then + echo "SKIPPED SHUTDOWN..." + echo "" + echo "RUN FOLLOWING TO CLEAN UP:" + echo "pkill -P ${NETWORK_RUNNER_PID} || true" + echo "kill -2 ${NETWORK_RUNNER_PID} || true" + echo "" +else + echo "SHUTTING DOWN..." + echo "" + # "e2e.test" already terminates the cluster for "test" mode + # just in case tests are aborted, manually terminate them again + echo "network-runner RPC server was running on NETWORK_RUNNER_PID ${NETWORK_RUNNER_PID} as test mode; terminating the process..." + pkill -P ${NETWORK_RUNNER_PID} || true + kill -2 ${NETWORK_RUNNER_PID} || true +fi + +echo "TEST SUCCESS" diff --git a/m1/scripts/tests.lint.sh b/m1/scripts/tests.lint.sh new file mode 100755 index 000000000..8035efca6 --- /dev/null +++ b/m1/scripts/tests.lint.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -xue + +if ! [[ "$0" =~ scripts/tests.lint.sh ]]; then + echo "must be run from repository root" + exit 255 +fi + +# https://rust-lang.github.io/rustup/installation/index.html +# rustup toolchain install nightly --allow-downgrade --profile minimal --component clippy +# +# https://github.com/rust-lang/rustfmt +# rustup component add rustfmt +# rustup component add rustfmt --toolchain nightly +# rustup component add clippy +# rustup component add clippy --toolchain nightly + +rustup default stable +cargo fmt --all --verbose -- --check + +# TODO: enable nightly fmt +rustup default nightly +cargo +nightly fmt --all -- --config-path .rustfmt.nightly.toml --verbose --check || true + +# TODO: enable this +cargo +nightly clippy --all --all-features -- -D warnings || true + +rustup default stable + +echo "ALL SUCCESS!" diff --git a/m1/scripts/tests.unit.sh b/m1/scripts/tests.unit.sh new file mode 100755 index 000000000..0f9daed91 --- /dev/null +++ b/m1/scripts/tests.unit.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -xue + +if ! [[ "$0" =~ scripts/tests.unit.sh ]]; then + echo "must be run from repository root" + exit 255 +fi + +RUST_LOG=debug cargo test --all --all-features \ +--exclude e2e \ +-- --show-output + +echo "ALL SUCCESS!" diff --git a/m1/scripts/tests.unused.sh b/m1/scripts/tests.unused.sh new file mode 100755 index 000000000..3cb93c9e0 --- /dev/null +++ b/m1/scripts/tests.unused.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -xue + +if ! [[ "$0" =~ scripts/tests.unused.sh ]]; then + echo "must be run from repository root" + exit 255 +fi + +# cargo install cargo-udeps --locked +# https://github.com/est31/cargo-udeps +cargo install cargo-udeps --locked +cargo +nightly udeps + +echo "ALL SUCCESS!" diff --git a/m1/subnet-request-proxy b/m1/subnet-request-proxy new file mode 160000 index 000000000..e538ec536 --- /dev/null +++ b/m1/subnet-request-proxy @@ -0,0 +1 @@ +Subproject commit e538ec536ed845020bdd23268bc8c5a6a2140f91 diff --git a/m1/subnet/Cargo.toml b/m1/subnet/Cargo.toml index 112355a0d..aaf8934f9 100644 --- a/m1/subnet/Cargo.toml +++ b/m1/subnet/Cargo.toml @@ -49,3 +49,9 @@ aptos-vm-genesis = { workspace = true } bcs = { workspace = true } aptos-node = { workspace = true, features = ["indexer"] } aptos-indexer-grpc-fullnode = { workspace = true } +aptos-protos = { workspace = true } +aptos-indexer = { workspace = true } + +# differs from workspace +clap = { version = "4.4.8", features = ["cargo", "derive"] } +uuid = "1.5.0" diff --git a/m1/subnet/src/bin/subnet/genesis.rs b/m1/subnet/src/bin/subnet/genesis.rs new file mode 100644 index 000000000..b364f1808 --- /dev/null +++ b/m1/subnet/src/bin/subnet/genesis.rs @@ -0,0 +1,11 @@ +use clap::{arg, Command}; + +pub const NAME: &str = "genesis"; + +#[must_use] +pub fn command() -> Command { + Command::new(NAME) + .about("Write a genesis file") + .arg(arg!( "Genesis message data")) + .arg_required_else_help(true) +} diff --git a/m1/subnet/src/bin/subnet/main.rs b/m1/subnet/src/bin/subnet/main.rs new file mode 100644 index 000000000..4c13cb444 --- /dev/null +++ b/m1/subnet/src/bin/subnet/main.rs @@ -0,0 +1,49 @@ +pub mod genesis; +pub mod vm_id; + +use std::io; + +use avalanche_types::{subnet as avasubnet}; +use clap::{crate_version, Command}; +use subnet::run_subnet; + +pub const APP_NAME: &str = "subnet"; + +#[tokio::main] +async fn main() -> io::Result<()> { + let matches = Command::new(APP_NAME) + .version(crate_version!()) + .about("Subnet") + .subcommands(vec![genesis::command(), vm_id::command()]) + .get_matches(); + + // ref. https://github.com/env-logger-rs/env_logger/issues/47 + env_logger::init_from_env( + env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), + ); + + match matches.subcommand() { + Some((genesis::NAME, sub_matches)) => { + let data = sub_matches.get_one::("DATA").expect("required"); + let genesis = data; + println!("{genesis}"); + + Ok(()) + } + + Some((vm_id::NAME, sub_matches)) => { + let vm_name = sub_matches.get_one::("VM_NAME").expect("required"); + let id = avasubnet::vm_name_to_id(vm_name)?; + println!("{id}"); + + Ok(()) + } + + _ => { + log::info!("starting subnet"); + run_subnet().await?; + + Ok(()) + } + } +} diff --git a/m1/subnet/src/bin/subnet/vm_id.rs b/m1/subnet/src/bin/subnet/vm_id.rs new file mode 100644 index 000000000..45602115f --- /dev/null +++ b/m1/subnet/src/bin/subnet/vm_id.rs @@ -0,0 +1,11 @@ +use clap::{arg, Command}; + +pub const NAME: &str = "vm-id"; + +#[must_use] +pub fn command() -> Command { + Command::new(NAME) + .about("Converts a given Vm name string to Vm Id") + .arg(arg!( "A name of the Vm")) + .arg_required_else_help(true) +} diff --git a/m1/subnet/src/lib.rs b/m1/subnet/src/lib.rs new file mode 100644 index 000000000..86da69662 --- /dev/null +++ b/m1/subnet/src/lib.rs @@ -0,0 +1,16 @@ +pub mod api; +pub mod block; +pub mod state; +pub mod vm; + +use std::io; + +use avalanche_types::subnet; +use tokio::sync::broadcast::{self, Receiver, Sender}; + +pub async fn run_subnet() -> io::Result<()> { + let (stop_ch_tx, stop_ch_rx): (Sender<()>, Receiver<()>) = broadcast::channel(1); + let vm_server = subnet::rpc::vm::server::Server::new(vm::Vm::new(), stop_ch_tx); + log::info!("readying server"); + subnet::rpc::vm::serve(vm_server, stop_ch_rx).await +} \ No newline at end of file diff --git a/m1/subnet/src/main.rs b/m1/subnet/src/main.rs deleted file mode 100644 index f79bd7bb4..000000000 --- a/m1/subnet/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::io; - -use avalanche_types::subnet; -use tokio::sync::broadcast::{self, Receiver, Sender}; - -mod vm; -mod state; -mod block; -mod api; - -#[tokio::main] -async fn main() -> io::Result<()> { - env_logger::init_from_env( - env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), - ); - let (stop_ch_tx, stop_ch_rx): (Sender<()>, Receiver<()>) = broadcast::channel(1); - let vm_server = subnet::rpc::vm::server::Server::new(vm::Vm::new(), stop_ch_tx); - subnet::rpc::vm::serve(vm_server, stop_ch_rx).await -} diff --git a/m1/subnet/src/vm/mod.rs b/m1/subnet/src/vm/mod.rs index 54b3a98db..c8a67b3c4 100644 --- a/m1/subnet/src/vm/mod.rs +++ b/m1/subnet/src/vm/mod.rs @@ -56,14 +56,23 @@ use aptos_types::validator_signer::ValidatorSigner; use aptos_vm::AptosVM; use aptos_vm_genesis::{GENESIS_KEYPAIR, test_genesis_change_set_and_validators}; use aptos_node::indexer::bootstrap_indexer; -use aptos_indexer_grpc_fullnode::runtime::bootstrap as bootstrap_indexer_grpc; +use aptos_indexer::runtime::run_forever; +// use aptos_indexer_grpc_fullnode::runtime::bootstrap as bootstrap_indexer_grpc; +use aptos_indexer_grpc_fullnode::runtime::FullnodeDataService; +use aptos_protos::internal::fullnode::v1::fullnode_data_server::{FullnodeData, FullnodeDataServer}; +use std::net::ToSocketAddrs; use crate::{block::Block, state}; use crate::api::chain_handlers::{AccountStateArgs, BlockArgs, ChainHandler, ChainService, GetTransactionByVersionArgs, PageArgs, RpcEventHandleReq, RpcEventNumReq, RpcReq, RpcRes, RpcTableReq}; use crate::api::static_handlers::{StaticHandler, StaticService}; +use tonic::{transport::Server, Request, Response, Status}; +use uuid::Uuid; const VERSION: &str = env!("CARGO_PKG_VERSION"); const MOVE_DB_DIR: &str = ".move-chain-data"; +pub fn get_db_name(suffix : &str) -> String { + format!("{}-{}", MOVE_DB_DIR, suffix) +} #[derive(Serialize, Deserialize, Clone)] pub struct AptosData( @@ -1302,7 +1311,9 @@ impl Vm { Ok(()) } - async fn init_aptos(&mut self) { + async fn init_aptos(&mut self, uuid : &str) { + + let db_name = get_db_name(uuid); // generate the test genesis let (genesis, validators) = test_genesis_change_set_and_validators(Some(1)); @@ -1316,7 +1327,7 @@ impl Vm { let genesis_txn = Transaction::GenesisTransaction(WriteSetPayload::Direct(genesis)); let p = format!("{}/{}", dirs::home_dir().unwrap().to_str().unwrap(), - MOVE_DB_DIR); + db_name); if !fs::metadata(p.clone().as_str()).is_ok() { fs::create_dir_all(p.as_str()).unwrap(); } @@ -1341,14 +1352,39 @@ impl Vm { let (mempool_client_sender, mut mempool_client_receiver) = futures_mpsc::channel::(10); let sender = MempoolClientSender::from(mempool_client_sender.clone()); - let node_config = NodeConfig::default(); + let mut node_config = NodeConfig::default(); + + + node_config.indexer.enabled = true; + // indexer config + node_config.indexer.processor = Some("default_processor".to_string()); + node_config.indexer.check_chain_id = Some(false); + node_config.indexer.skip_migrations = Some(false); + node_config.indexer.fetch_tasks = Some(4); + node_config.indexer.processor_tasks = Some(4); + node_config.indexer.emit_every = Some(4); + node_config.indexer.batch_size = Some(8); + node_config.indexer.gap_lookback_versions = Some(4); + + node_config.indexer_grpc.enabled = true; + + // indexer_grpc config + // let processor_task_count = node_config.indexer_grpc.processor_task_count.unwrap(); + // let processor_batch_size = node_config.indexer_grpc.processor_batch_size.unwrap(); + // let output_batch_size = node_config.indexer_grpc.output_batch_size.unwrap(); + // let address = node_config.indexer_grpc.address.clone().unwrap(); + node_config.indexer_grpc.processor_batch_size = Some(4); + node_config.indexer_grpc.processor_task_count = Some(4); + node_config.indexer_grpc.output_batch_size = Some(4); + node_config.indexer_grpc.address = Some(String::from("0.0.0.0")); + let context = Context::new(ChainId::test(), db.1.reader.clone(), sender, node_config.clone()); // initialze the raw api self.api_context = Some(context.clone()); - let service = get_raw_api_service(Arc::new(context)); + let service = get_raw_api_service(Arc::new(context.clone())); self.api_service = Some(service); self.core_mempool = Some(Arc::new(RwLock::new(CoreMempool::new(&node_config)))); self.check_pending_tx().await; @@ -1370,12 +1406,38 @@ impl Vm { } }); - // start the indexer service - tokio::task::spawn(async move { - bootstrap_indexer_grpc(&node_config, ChainId::test(), db.1.reader.clone(), mempool_client_sender.clone()).unwrap(); - bootstrap_indexer(&node_config, ChainId::test(), db.1.reader.clone(), MempoolClientSender::from(mempool_client_sender.clone())).unwrap(); - }); + // start the indexer services (this is already sent to the background, so I think we're good) + // bootstrap_indexer_grpc(&node_config, ChainId::test(), db.1.reader.clone(), mempool_client_sender.clone()).unwrap(); + let indexer_context = Arc::new(context.clone()); + let indexer_config = node_config.indexer.clone(); + let server = FullnodeDataService { + context: indexer_context.clone(), + processor_task_count: 4, + processor_batch_size: 4, + output_batch_size: 4, + }; + + tokio::spawn(async move { + + println!("Starting indexer gRPC service."); + match Server::builder() + .add_service(FullnodeDataServer::new(server)) + .serve(String::from("0.0.0.0:8090").to_socket_addrs().unwrap().next().unwrap()) + .await + { + Ok(_) => { + println!("Indexer "); + }, + Err(e) => { + eprintln!("Failed to start server"); + } + } + }); + tokio::spawn(async move { + println!("Starting indexer trailer."); + run_forever(indexer_config, indexer_context.clone()).await; + }); } } @@ -1673,6 +1735,8 @@ impl CommonVm for Vm _fxs: &[snow::engine::common::vm::Fx], app_sender: Self::AppSender, ) -> io::Result<()> { + let uuid = Uuid::new_v4().to_string(); + log::info!("initializing M1 Vm {}", uuid); let mut vm_state = self.state.write().await; vm_state.ctx = ctx.clone(); let current = db_manager.current().await?; @@ -1686,7 +1750,8 @@ impl CommonVm for Vm self.app_sender = Some(app_sender); drop(vm_state); - self.init_aptos().await; + + self.init_aptos(&uuid).await; let mut vm_state = self.state.write().await; let genesis = "hello world"; let has_last_accepted = state.has_last_accepted_block().await?; diff --git a/m1/tests/e2e/Cargo.toml b/m1/tests/e2e/Cargo.toml new file mode 100644 index 000000000..7a48f4c2c --- /dev/null +++ b/m1/tests/e2e/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "e2e" +version = "0.0.0" +edition = "2021" +rust-version = "1.70" +publish = false +description = "e2e tests for timestampvm" +license = "BSD-3-Clause" +homepage = "https://avax.network" + +[dependencies] + +[dev-dependencies] +avalanche-installer = "0.0.77" +avalanche-network-runner-sdk = "0.3.3" # https://crates.io/crates/avalanche-network-runner-sdk +avalanche-types = { version = "0.1.4", features = ["jsonrpc_client", "subnet"] } # https://crates.io/crates/avalanche-types +env_logger = "0.10.1" +log = "0.4.19" +random-manager = "0.0.5" +serde_json = "1.0.108" # https://github.com/serde-rs/json/releases +tempfile = "3.8.1" +subnet = { path = "../../subnet" } +tokio = { workspace = true } # https://github.com/tokio-rs/tokio/releases + diff --git a/m1/tests/e2e/src/lib.rs b/m1/tests/e2e/src/lib.rs new file mode 100644 index 000000000..6e11c1a50 --- /dev/null +++ b/m1/tests/e2e/src/lib.rs @@ -0,0 +1,31 @@ +#[cfg(test)] +mod tests; + +#[must_use] +pub fn get_network_runner_grpc_endpoint() -> (String, bool) { + match std::env::var("NETWORK_RUNNER_GRPC_ENDPOINT") { + Ok(s) => (s, true), + _ => (String::new(), false), + } +} + +#[must_use] +pub fn get_network_runner_enable_shutdown() -> bool { + matches!(std::env::var("NETWORK_RUNNER_ENABLE_SHUTDOWN"), Ok(_)) +} + +#[must_use] +pub fn get_avalanchego_path() -> (String, bool) { + match std::env::var("AVALANCHEGO_PATH") { + Ok(s) => (s, true), + _ => (String::new(), false), + } +} + +#[must_use] +pub fn get_vm_plugin_path() -> (String, bool) { + match std::env::var("VM_PLUGIN_PATH") { + Ok(s) => (s, true), + _ => (String::new(), false), + } +} diff --git a/m1/tests/e2e/src/tests/mod.rs b/m1/tests/e2e/src/tests/mod.rs new file mode 100644 index 000000000..c1285fbf9 --- /dev/null +++ b/m1/tests/e2e/src/tests/mod.rs @@ -0,0 +1,236 @@ +use std::{ + io, + fs::{self, File}, + path::Path, + str::FromStr, + thread, + time::{Duration, Instant}, io::Write, +}; + +use avalanche_network_runner_sdk::{BlockchainSpec, Client, GlobalConfig, StartRequest}; +use avalanche_types::{ids, jsonrpc::client::info as avalanche_sdk_info, subnet}; + +const AVALANCHEGO_VERSION: &str = "v1.10.9"; + +// todo: extracted from genesis method +// todo: really we should use a genesis once more +pub fn sync_genesis(byte_string : &str, file_path: &str) -> io::Result<()> { + log::info!("syncing genesis to '{}'", file_path); + + let path = Path::new(file_path); + let parent_dir = path.parent().expect("Invalid path"); + fs::create_dir_all(parent_dir)?; + + let d = byte_string.as_bytes(); + + let mut f = File::create(file_path)?; + f.write_all(&d)?; + + Ok(()) +} + +#[tokio::test] +async fn e2e() { + let _ = env_logger::builder() + .filter_level(log::LevelFilter::Info) + .is_test(true) + .try_init(); + + let (ep, is_set) = crate::get_network_runner_grpc_endpoint(); + assert!(is_set); + + let cli = Client::new(&ep).await; + + log::info!("ping..."); + let resp = cli.ping().await.expect("failed ping"); + log::info!("network-runner is running (ping response {:?})", resp); + + let (vm_plugin_path, exists) = crate::get_vm_plugin_path(); + log::info!("Vm Plugin path: {vm_plugin_path}"); + assert!(exists); + assert!(Path::new(&vm_plugin_path).exists()); + + let vm_id = Path::new(&vm_plugin_path) + .file_stem() + .unwrap() + .to_str() + .unwrap() + .to_string(); + // ! for now, we hardcode the id to be subnet for orchestration + let vm_id = subnet::vm_name_to_id("subnet").unwrap(); + + let (mut avalanchego_exec_path, _) = crate::get_avalanchego_path(); + let plugins_dir = if !avalanchego_exec_path.is_empty() { + let parent_dir = Path::new(&avalanchego_exec_path) + .parent() + .expect("unexpected None parent"); + parent_dir + .join("plugins") + .as_os_str() + .to_str() + .unwrap() + .to_string() + } else { + let exec_path = avalanche_installer::avalanchego::github::download( + None, + None, + Some(AVALANCHEGO_VERSION.to_string()), + ) + .await + .unwrap(); + avalanchego_exec_path = exec_path; + avalanche_installer::avalanchego::get_plugin_dir(&avalanchego_exec_path) + }; + + log::info!( + "copying vm plugin {} to {}/{}", + vm_plugin_path, + plugins_dir, + vm_id + ); + + fs::create_dir(&plugins_dir).unwrap(); + fs::copy( + &vm_plugin_path, + Path::new(&plugins_dir).join(vm_id.to_string()), + ) + .unwrap(); + + // write some random genesis file + let genesis = random_manager::secure_string(10); + + let genesis_file_path = random_manager::tmp_path(10, None).unwrap(); + sync_genesis(genesis.as_ref(), &genesis_file_path).unwrap(); + + log::info!( + "starting {} with avalanchego {}, genesis file path {}", + vm_id, + &avalanchego_exec_path, + genesis_file_path, + ); + let resp = cli + .start(StartRequest { + exec_path: avalanchego_exec_path, + num_nodes: Some(5), + plugin_dir: plugins_dir, + global_node_config: Some( + serde_json::to_string(&GlobalConfig { + log_level: String::from("info"), + }) + .unwrap(), + ), + blockchain_specs: vec![BlockchainSpec { + vm_name: String::from("subnet"), + genesis: genesis_file_path.to_string(), + // blockchain_alias : String::from("subnet"), // todo: this doesn't always work oddly enough, need to debug + ..Default::default() + }], + ..Default::default() + }) + .await + .expect("failed start"); + log::info!( + "started avalanchego cluster with network-runner: {:?}", + resp + ); + + // enough time for network-runner to get ready + thread::sleep(Duration::from_secs(20)); + + log::info!("checking cluster healthiness..."); + let mut ready = false; + + let timeout = Duration::from_secs(300); + let interval = Duration::from_secs(15); + let start = Instant::now(); + let mut cnt: u128 = 0; + loop { + let elapsed = start.elapsed(); + if elapsed.gt(&timeout) { + break; + } + + let itv = { + if cnt == 0 { + // first poll with no wait + Duration::from_secs(1) + } else { + interval + } + }; + thread::sleep(itv); + + ready = { + match cli.health().await { + Ok(_) => { + log::info!("healthy now!"); + true + } + Err(e) => { + log::warn!("not healthy yet {}", e); + false + } + } + }; + if ready { + break; + } + + cnt += 1; + } + assert!(ready); + + log::info!("checking status..."); + let mut status = cli.status().await.expect("failed status"); + loop { + let elapsed = start.elapsed(); + if elapsed.gt(&timeout) { + break; + } + + if let Some(ci) = &status.cluster_info { + if !ci.custom_chains.is_empty() { + break; + } + } + + log::info!("retrying checking status..."); + thread::sleep(interval); + status = cli.status().await.expect("failed status"); + } + + assert!(status.cluster_info.is_some()); + let cluster_info = status.cluster_info.unwrap(); + let mut rpc_eps: Vec = Vec::new(); + for (node_name, iv) in cluster_info.node_infos.into_iter() { + log::info!("{}: {}", node_name, iv.uri); + rpc_eps.push(iv.uri.clone()); + } + let mut blockchain_id = ids::Id::empty(); + for (k, v) in cluster_info.custom_chains.iter() { + log::info!("custom chain info: {}={:?}", k, v); + if v.chain_name == "subnet" { + blockchain_id = ids::Id::from_str(&v.chain_id).unwrap(); + break; + } + } + log::info!("avalanchego RPC endpoints: {:?}", rpc_eps); + + let resp = avalanche_sdk_info::get_network_id(&rpc_eps[0]) + .await + .unwrap(); + let network_id = resp.result.unwrap().network_id; + log::info!("network Id: {}", network_id); + + // keep alive by sleeping for duration provided by SUBNET_TIMEOUT environment variable + // use sensible default + let timeout = Duration::from_secs( + std::env::var("SUBNET_TIMEOUT") + .unwrap_or_else(|_| "0".to_string()) + .parse::() + .unwrap(), + ); + log::info!("sleeping for {} seconds", timeout.as_secs()); + thread::sleep(timeout); + +} diff --git a/movement-sdk/.cargo/config.toml b/movement-sdk/.cargo/config.toml new file mode 100644 index 000000000..f93b5556e --- /dev/null +++ b/movement-sdk/.cargo/config.toml @@ -0,0 +1,33 @@ +[alias] +xclippy = [ + "clippy", + "--workspace", + "--all-targets", + "--", + "-Dwarnings", + "-Wclippy::all", + "-Aclippy::upper_case_acronyms", + "-Aclippy::enum-variant-names", + "-Aclippy::result-large-err", + "-Aclippy::mutable-key-type", +] + +[build] +rustflags = ["--cfg", "tokio_unstable", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes"] + +# TODO(grao): Figure out whether we should enable other cpu features, and whether we should use a different way to configure them rather than list every single one here. +[target.x86_64-unknown-linux-gnu] +rustflags = ["--cfg", "tokio_unstable", "-C", "link-arg=-fuse-ld=lld", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes", "-C", "target-feature=+sse4.2"] + +# 64 bit MSVC +[target.x86_64-pc-windows-msvc] +rustflags = [ + "--cfg", + "tokio_unstable", + "-C", + "force-frame-pointers=yes", + "-C", + "force-unwind-tables=yes", + "-C", + "link-arg=/STACK:8000000" # Set stack to 8 MB +] diff --git a/movement-sdk/.gitignore b/movement-sdk/.gitignore new file mode 100644 index 000000000..1de565933 --- /dev/null +++ b/movement-sdk/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/movement-sdk/Cargo.lock b/movement-sdk/Cargo.lock new file mode 100644 index 000000000..82498141b --- /dev/null +++ b/movement-sdk/Cargo.lock @@ -0,0 +1,3069 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "avalanche-types" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "768d08fdaf7a9fcd16062f00af5985a729357bbdedb83eb5a8f196424c0186fe" +dependencies = [ + "async-trait", + "base64 0.21.5", + "bech32", + "blst", + "bs58 0.5.0", + "bytes", + "cert-manager", + "chrono", + "cmp-manager", + "ecdsa", + "ethers-core", + "futures", + "hex", + "hmac", + "http", + "hyper", + "jsonrpc-core", + "k256", + "lazy_static", + "log", + "num-derive", + "num-traits", + "prefix-manager", + "primitive-types", + "prost", + "rand", + "ring 0.16.20", + "ripemd", + "rust-embed", + "semver", + "serde", + "serde_json", + "serde_with", + "serde_yaml", + "sha2", + "sha3", + "spki", + "strum", + "thiserror", + "tokio", + "tokio-stream", + "tonic 0.9.2", + "tonic-health", + "tonic-reflection", + "tower-service", + "url", + "zerocopy", + "zeroize", +] + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "sha2", + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cert-manager" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "166da6fda67aa44381158b8ad9c3b28d842951791c431ce61333e62cb9b05d5b" +dependencies = [ + "log", + "rand", + "random-manager", + "rcgen", + "rsa", + "rustls", + "rustls-pemfile", + "x509-parser 0.15.1", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "channel-avalanche" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "avalanche-types", + "movement-sdk", + "tokio", + "tonic 0.8.3", +] + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "cmp-manager" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f5e2b424191b35b798b06e6c67fa5a5440a098925d931d7e91511d7d8fe275" + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.38", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers-core" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da5fa198af0d3be20c19192df2bd9590b92ce09a8421e793bec8851270f1b05" +dependencies = [ + "arrayvec", + "bytes", + "chrono", + "elliptic-curve", + "ethabi", + "generic-array", + "hex", + "k256", + "num_enum", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[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", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", + "serde", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "k256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" + +[[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 = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "movement-sdk" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "serde", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prefix-manager" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21965b29633f6d9b2ebc05ba4c348173389e38da66de71dcd0b2bd8b9cde713c" + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "random-manager" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2557c07161d4d805cd7e711d0648b292be9e727d9678d078bab052278cd1b71" +dependencies = [ + "bs58 0.4.0", + "lazy_static", + "primitive-types", + "rand", + "ring 0.16.20", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem", + "ring 0.16.20", + "time", + "x509-parser 0.14.0", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rsa" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rust-embed" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e7d90385b59f0a6bf3d3b757f3ca4ece2048265d70db20a2016043d4509a40" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3d8c6fd84090ae348e63a84336b112b5c3918b3bf0493a581f7bd8ee623c29" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.38", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "873feff8cb7bf86fdf0a71bb21c95159f4e4a37dd7a4bd1855a940909b583ada" +dependencies = [ + "sha2", + "walkdir", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.38.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.21.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +dependencies = [ + "log", + "ring 0.17.5", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64 0.21.5", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.1.0", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "serde_yaml" +version = "0.9.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" +dependencies = [ + "indexmap 2.1.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 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.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[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.38", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "flate2", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.5", + "bytes", + "flate2", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-health" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080964d45894b90273d2b1dd755fdd114560db8636bb41cea615213c45043c4d" +dependencies = [ + "async-stream", + "prost", + "tokio", + "tokio-stream", + "tonic 0.9.2", +] + +[[package]] +name = "tonic-reflection" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0543d7092032041fbeac1f2c84304537553421a11a623c2301b12ef0264862c7" +dependencies = [ + "prost", + "prost-types", + "tokio", + "tokio-stream", + "tonic 0.9.2", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "web-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs", + "base64 0.13.1", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "ring 0.16.20", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "x509-parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "zerocopy" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96f8f25c15a0edc9b07eb66e7e6e97d124c0505435c382fde1ab7ceb188aa956" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "855e0f6af9cd72b87d8a6c586f3cb583f5cdcc62c2c80869d8cd7e96fdf7ee20" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[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.38", +] diff --git a/movement-sdk/Cargo.toml b/movement-sdk/Cargo.toml new file mode 100644 index 000000000..685f92bbd --- /dev/null +++ b/movement-sdk/Cargo.toml @@ -0,0 +1,24 @@ +[workspace] +resolver = "2" +members = [ + "movement-sdk", + "movement-sdk-avalanche" +] + +[workspace.package] +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +authors = ["Liam Monninger "] +homepage = "https://www.movementlabs.xyz" +publish = false +repository = "https://github.com/movemntdev/m2" +rust-version = "1.70" + +[workspace.dependencies] +async-trait = { version = "0.1" } +anyhow = { version = "1" } # For flexible error handling +avalanche-types = { version = "0.1.3", features = ["subnet", "codec_base64"] } +movement-sdk = { path = "movement-sdk" } +tokio = { version = "1.21.0", features = ["full"] } +serde = { version = "1.0", features = ["derive"] } \ No newline at end of file diff --git a/movement-sdk/movement-sdk-avalanche/Cargo.toml b/movement-sdk/movement-sdk-avalanche/Cargo.toml new file mode 100644 index 000000000..fcc4c733a --- /dev/null +++ b/movement-sdk/movement-sdk-avalanche/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "channel-avalanche" +version = "0.1.0" +edition = "2021" + +[dependencies] +async-trait = { workspace = true } +anyhow = { workspace = true } +avalanche-types = { workspace = true } +movement-sdk = { workspace = true } +tokio = { workspace = true } +tonic = { version = "0.8.3", features = ["gzip"] } \ No newline at end of file diff --git a/movement-sdk/movement-sdk-avalanche/src/data_availability/mod.rs b/movement-sdk/movement-sdk-avalanche/src/data_availability/mod.rs new file mode 100644 index 000000000..c98ee9dea --- /dev/null +++ b/movement-sdk/movement-sdk-avalanche/src/data_availability/mod.rs @@ -0,0 +1,82 @@ +use avalanche_types::{ + choices, + ids::{self, Id}, + subnet::rpc::consensus::snowman::{ + Decidable, + Block + } +}; +use movement_sdk::DataAvailabilityLayer; +use std::sync::Arc; +use tokio::sync::RwLock; +use std::io; + +#[derive(Debug, Clone)] +pub struct AvalancheBlock< + Block, + BlockId, + DA : DataAvailabilityLayer +>{ + pub inner_block: Block, + pub data_availability_layer: Arc>, +} + +impl < + Block, + BlockId, + DA : DataAvailabilityLayer +> AvalancheBlock { + + pub fn new( + inner_block: Block, + data_availability_layer: Arc>, + ) -> Self { + Self { + inner_block, + data_availability_layer, + } + } + +} + +impl < + Block, + BlockId, + DA : DataAvailabilityLayer +> Into> for (Block, Arc>) { + fn into(self) -> AvalancheBlock { + AvalancheBlock::new(self.0, self.1) + } +} + +#[async_trait::async_trait] +impl < + Block : Sync + Clone, + BlockId, + DA : DataAvailabilityLayer + Sync + Send +> Decidable for AvalancheBlock { + + async fn id(&self) -> ids::Id { + unimplemented!("todo: implement id"); + // ids::Id::empty() + } + + /// Implements "snowman.Block.choices.Decidable" + async fn status(&self) -> choices::status::Status { + unimplemented!("todo: implement status"); + // choices::status::Status::Unknown(String::from("unimplemented")) + } + + async fn accept(&mut self) -> io::Result<()> { + let data_availability_layer = self.data_availability_layer.read().await; + data_availability_layer.accept_block(self.inner_block.clone()).await?; + Ok(()) + } + + async fn reject(&mut self) -> io::Result<()> { + let data_availability_layer = self.data_availability_layer.read().await; + data_availability_layer.reject_block(self.inner_block.clone()).await?; + Ok(()) + } + +} \ No newline at end of file diff --git a/movement-sdk/movement-sdk-avalanche/src/lib.rs b/movement-sdk/movement-sdk-avalanche/src/lib.rs new file mode 100644 index 000000000..15cca4a90 --- /dev/null +++ b/movement-sdk/movement-sdk-avalanche/src/lib.rs @@ -0,0 +1,2 @@ +pub mod data_availability; +pub mod proposer; \ No newline at end of file diff --git a/movement-sdk/movement-sdk-avalanche/src/proposer/mod.rs b/movement-sdk/movement-sdk-avalanche/src/proposer/mod.rs new file mode 100644 index 000000000..e69de29bb diff --git a/movement-sdk/movement-sdk/Cargo.toml b/movement-sdk/movement-sdk/Cargo.toml new file mode 100644 index 000000000..84038dd3f --- /dev/null +++ b/movement-sdk/movement-sdk/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "movement-sdk" +version = "0.1.0" +edition = "2021" + +[dependencies] +async-trait = { workspace = true } +anyhow = { workspace = true } +serde = { workspace = true } \ No newline at end of file diff --git a/movement-sdk/movement-sdk/src/lib.rs b/movement-sdk/movement-sdk/src/lib.rs new file mode 100644 index 000000000..7d87be97b --- /dev/null +++ b/movement-sdk/movement-sdk/src/lib.rs @@ -0,0 +1,204 @@ +use async_trait::async_trait; +use core::fmt::Debug; +use serde::{Deserialize, Serialize}; + +pub trait Layer : Debug + Clone { + +} + +// Top-level definition of traits. +// Complex extensions and integrations should be defined in the submodules. +#[async_trait] +pub trait SequencerLayer : Layer { + + type Transaction; + type TransactionId; + + // Receives a transaction and internally sends it on to the next layer. + async fn receive_transaction( + &self, + transaction: Self::Transaction + ) -> Result<(), anyhow::Error>; + + // Gets a received transaction. + async fn get_transaction( + &self, + transaction_id: Self::TransactionId + ) -> Result, anyhow::Error>; + +} + +#[async_trait] +pub trait ProposerLayer : Layer { + + type Transaction; + type Block; + type BlockId; + + /// Gets the next transaction from the previous layer. + async fn get_next_transaction( + &self + ) -> Result, anyhow::Error>; + + /// Constructs a block from some transactions + async fn build_block( + &self, + ) -> Result; + + /// Sends a constructed block to the next layer. + async fn send_block( + &self, + block: Self::Block + ) -> Result<(), anyhow::Error>; + + /// Gets a constructed and sent block + async fn get_block( + &self, + block_id: Self::BlockId + ) -> Result, anyhow::Error>; + + +} + +#[async_trait] +pub trait DataAvailabilityLayer : Layer { + + type Block; + type BlockId; + + /// Gets the next block from the previous layer. + async fn get_next_block( + &self + ) -> Result, anyhow::Error>; + + /// Accepts a block, effectively sending it to the next layer or place retrievable from the next layer, i.e., the execution layer. + async fn accept_block( + &self, + block: Self::Block + ) -> Result<(), anyhow::Error>; + + /// Rejects a block (sometimes this won't be used). + async fn reject_block( + &self, + block: Self::Block + ) -> Result<(), anyhow::Error>; + + /// Gets a block that was either accepted or rejected by the data availability layer. + async fn get_block( + &self, + block_id: Self::BlockId + ) -> Result, anyhow::Error>; + +} + +#[async_trait] +pub trait ExecutionLayer : Layer { + + type Block; + type BlockId; + type ChangeSet; + + // Gets the next block from the previous layer. + async fn get_next_block( + &self + ) -> Result, anyhow::Error>; + + // Executes a block and produces a change set. + async fn execute_block( + &self, + block: Self::Block + ) -> Result; + + // Sends a change set to the next layer, i.e., the storage layer. + async fn send_change_set( + &self, + change_set: Self::ChangeSet + ) -> Result<(), anyhow::Error>; + + // Gets an executed block + async fn get_block( + &self, + block_id: Self::BlockId + ) -> Result, anyhow::Error>; + +} + +#[async_trait] +pub trait StorageLayer : Layer { + + type Block; + type BlockId; + type ChangeSet; + type StateEntry; + type Address; + + // Gets the next change set from the previous layer. + async fn get_next_change_set( + &self + ) -> Result, anyhow::Error>; + + // Applies a change set to the storage layer. + async fn derive_state( + &self, + change_set: Self::ChangeSet + ) -> Result<(), anyhow::Error>; + + // Gets a state entry from the storage layer. + async fn get_state_entry( + &self, + address: Self::Address + ) -> Result, anyhow::Error>; + + // Gets an applied change set + async fn get_change_set( + &self, + block_id: Self::BlockId + ) -> Result, anyhow::Error>; + +} + +#[async_trait] +pub trait SettlementLayer : Layer { + + type Block; + type BlockId; + type Commitment; + + // Gets the next block from the previous layer + async fn get_next_block( + &self + ) -> Result, anyhow::Error>; + + // Gets a commitment from the previous layer + async fn build_commitment( + &self, + ) -> Result; + + // Applies a commitment to itself + async fn apply_commitment( + &self, + commitment: Self::Commitment + ) -> Result<(), anyhow::Error>; + + +} + +#[async_trait] +pub trait MessagingLayer : Layer { + + type Message; + + // Sends a message to other layers. + async fn send_message( + &self, + message: Self::Message + ) -> Result<(), anyhow::Error>; + + // Receives a message from another layer and handles it internally. + async fn receive_message( + &self, + message: Self::Message + ) -> Result<(), anyhow::Error>; + + +} \ No newline at end of file diff --git a/scripts/movementctl.sh b/scripts/movementctl.sh index 94d386431..c20f24e8a 100755 --- a/scripts/movementctl.sh +++ b/scripts/movementctl.sh @@ -10,11 +10,11 @@ # Usage: movementctl [start/stop] [fuji/local/subnet-proxy] [--foreground] # # Author: Liam Monninger -# Version: 1.0 +# Version: 2.0 ################################################################################ VM_NAME="movement" -SUBNET_ID="2gLyawqthdiyrJktJmdnDAb1XVc6xwJXU6iJKu3Uwj21F2mXAK" +SUBNET_ID="K4GygGTpKkNzzjiLfZVsmQduGqSFztJx4nk52CvA1afcFAhsH" PID_DIR="$HOME/.movement/pid" mkdir -p "$PID_DIR" @@ -39,24 +39,10 @@ function start_avalanchego() { # Starts the avalanche-network-runner server function start_avalanche_network_runner() { if [[ $RUN_IN_FOREGROUND == "true" ]]; then - # Start a new tmux session in detached mode and run the first command - tmux new-session -d -s lnet 'avalanche-network-runner server --log-level debug' - - # Introduce a delay (e.g., 5 seconds) - sleep 5 - - # Run the second command in the current terminal - avalanche-network-runner control create-blockchains '[{"vm_name":"'$VM_NAME'", "subnet_id": "'$SUBNET_ID'"}]' - - tmux attach-session -t lnet - + SUBNET_TIMEOUT=10000000000000 $HOME/.movement/M1/m1/run.debug.sh else - avalanche-network-runner server --log-level debug & + SUBNET_TIMEOUT=10000000000000 $HOME/.movement/M1/m1/run.debug.sh & echo $! >> "$PID_DIR/avalanche_network_runner.pid" - # Introduce a delay (e.g., 5 seconds) - sleep 5 - # Run the second command in the current terminal - avalanche-network-runner control create-blockchains '[{"vm_name":"'$VM_NAME'", "subnet_id": "'$SUBNET_ID'"}]' fi } @@ -106,7 +92,7 @@ function stop_process() { function start() { case $1 in fuji) - start_avalanchego "fuji" "2gLyawqthdiyrJktJmdnDAb1XVc6xwJXU6iJKu3Uwj21F2mXAK" + start_avalanchego "fuji" $SUBNET_ID ;; local) start_avalanche_network_runner diff --git a/third-party/aptos-core b/third-party/aptos-core deleted file mode 160000 index 0c4e264c8..000000000 --- a/third-party/aptos-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0c4e264c85e8ee905a4f96a29834d200f37d35ef diff --git a/third-party/aptos-core-1.7 b/third-party/aptos-core-1.7 deleted file mode 160000 index 94ff2f0d9..000000000 --- a/third-party/aptos-core-1.7 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 94ff2f0d9e35441ab9fc57a459f64e1afa5ca70d diff --git a/vendors/aptos-core b/vendors/aptos-core new file mode 160000 index 000000000..e4c39ec37 --- /dev/null +++ b/vendors/aptos-core @@ -0,0 +1 @@ +Subproject commit e4c39ec37274a141b2b4c859285897f5b43d8a71 diff --git a/vendors/aptos-core-1.7 b/vendors/aptos-core-1.7 new file mode 160000 index 000000000..94d5867d5 --- /dev/null +++ b/vendors/aptos-core-1.7 @@ -0,0 +1 @@ +Subproject commit 94d5867d5d48aba93b24615096c25982184d56fb diff --git a/third-party/ed25519-dalek b/vendors/ed25519-dalek similarity index 100% rename from third-party/ed25519-dalek rename to vendors/ed25519-dalek diff --git a/vendors/move/Cargo.lock b/vendors/move/Cargo.lock new file mode 100644 index 000000000..782f16950 --- /dev/null +++ b/vendors/move/Cargo.lock @@ -0,0 +1,4533 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.9", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "ansi_term" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] +name = "arbitrary" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bcs" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd3ffe8b19a604421a5d461d4a70346223e535903fbc3067138bddbebddcf77" +dependencies = [ + "serde", + "thiserror", +] + +[[package]] +name = "better_any" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b359aebd937c17c725e19efcb661200883f04c49c53e7132224dac26da39d4a0" +dependencies = [ + "better_typeid_derive", +] + +[[package]] +name = "better_typeid_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3deeecb812ca5300b7d3f66f730cc2ebd3511c3d36c691dd79c165d5b19a26e3" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "bstr" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytecode-interpreter-crypto" +version = "0.1.0" +dependencies = [ + "anyhow", + "curve25519-dalek-fiat", + "ed25519-dalek-fiat", + "sha2 0.9.9", + "sha3", +] + +[[package]] +name = "bytecode-interpreter-testsuite" +version = "0.1.0" +dependencies = [ + "anyhow", + "datatest-stable", + "move-command-line-common", + "move-prover-test-utils", + "move-stackless-bytecode-interpreter", + "move-stdlib", + "move-unit-test", +] + +[[package]] +name = "bytecode-verifier-libfuzzer" +version = "0.0.0" +dependencies = [ + "arbitrary", + "libfuzzer-sys", + "move-binary-format", + "move-bytecode-verifier", + "move-core-types", +] + +[[package]] +name = "bytecode-verifier-tests" +version = "0.1.0" +dependencies = [ + "fail", + "hex", + "invalid-mutations", + "move-binary-format", + "move-bytecode-verifier", + "move-core-types", + "move-vm-config", + "petgraph", + "proptest", +] + +[[package]] +name = "bytecode-verifier-transactional-tests" +version = "0.1.0" +dependencies = [ + "datatest-stable", + "move-transactional-test-runner", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "time", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "chrono-tz" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term 0.12.1", + "atty", + "bitflags", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "3.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +dependencies = [ + "atty", + "bitflags", + "clap_derive 3.2.18", + "clap_lex 0.2.4", + "indexmap", + "once_cell", + "strsim 0.10.0", + "termcolor", + "textwrap 0.16.0", +] + +[[package]] +name = "clap" +version = "4.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c8d502cbaec4595d2e7d5f61e318f05417bd2b66fdc3809498f0d3fdf0bea27" +dependencies = [ + "clap_builder", + "clap_derive 4.4.0", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5891c7bc0edb3e1c2204fc5e94009affabeb1821c9e5fdc3959536c5c0bb984d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex 0.5.1", + "strsim 0.10.0", +] + +[[package]] +name = "clap_derive" +version = "3.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "clap_derive" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9fd1a5729c4548118d7d70ff234a44868d00489a4b6597b0b020918a0e91a1a" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" + +[[package]] +name = "codespan" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" +dependencies = [ + "codespan-reporting", + "serde", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +dependencies = [ + "libc", +] + +[[package]] +name = "criterion" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +dependencies = [ + "atty", + "cast", + "clap 2.34.0", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-cpu-time" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63aaaf47e457badbcb376c65a49d0f182c317ebd97dc6d1ced94c8e1d09c0f3a" +dependencies = [ + "criterion", + "libc", +] + +[[package]] +name = "criterion-plot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +dependencies = [ + "cfg-if", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossterm" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486d44227f71a1ef39554c0dc47e44b9f4139927c75043312690c3f476d1d788" +dependencies = [ + "bitflags", + "crossterm_winapi 0.8.0", + "libc", + "mio 0.7.14", + "parking_lot 0.11.2", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85525306c4291d1b73ce93c8acf9c339f9b213aef6c1d85c3830cbf1c16325c" +dependencies = [ + "bitflags", + "crossterm_winapi 0.9.0", + "libc", + "mio 0.7.14", + "parking_lot 0.11.2", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6966607622438301997d3dac0d2f6e9a90c68bb6bc1785ea98456ab93c0507" +dependencies = [ + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "csv" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "curve25519-dalek-fiat" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44339b9ecede7f72a0d3b012bf9bb5a616dc8bfde23ce544e42da075c87198f0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2 1.0.63", + "quote 1.0.28", + "scratch", + "syn 2.0.22", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core 0.9.7", +] + +[[package]] +name = "datatest-stable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eaf86e44e9f0a21f6e42d8e7f83c9ee049f081745eeed1c6f47a613c76e5977" +dependencies = [ + "libtest-mimic", + "regex", + "walkdir", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cdeb9ec472d588e539a818b2dee436825730da08ad0017c4b1a17676bdc8b7" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "deunicode" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", +] + +[[package]] +name = "dir-diff" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2860407d7d7e2e004bb2128510ad9e8d669e76fa005ccf567977b5d71b8b4a0b" +dependencies = [ + "walkdir", +] + +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users 0.3.5", + "winapi", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users 0.4.3", + "winapi", +] + +[[package]] +name = "dunce" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek-fiat" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97c6ac152eba578c1c53d2cefe8ad02e239e3d6f971b0f1ef3cb54cd66037fa0" +dependencies = [ + "curve25519-dalek-fiat", + "ed25519", + "rand 0.8.5", + "serde", + "serde_bytes", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "enum-compat-util" +version = "0.1.0" +dependencies = [ + "serde_yaml", +] + +[[package]] +name = "errno" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.45.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "ethnum" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0198b9d0078e0f30dedc7acbb21c974e838fc8fae3ee170128658a98cb2c1c04" + +[[package]] +name = "fail" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be3c61c59fdc91f5dbc3ea31ee8623122ce80057058be560654c5d410d181a6" +dependencies = [ + "lazy_static", + "log", + "rand 0.7.3", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "file_diff" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "globset" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags", + "ignore", + "walkdir", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[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.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "humansize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" + +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "internment" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab388864246d58a276e60e7569a833d9cc4cd75c66e5ca77c177dad38e59996" +dependencies = [ + "ahash", + "dashmap", + "hashbrown", + "once_cell", + "parking_lot 0.12.1", +] + +[[package]] +name = "invalid-mutations" +version = "0.1.0" +dependencies = [ + "move-binary-format", + "move-core-types", + "proptest", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "language-benchmarks" +version = "0.1.0" +dependencies = [ + "criterion", + "criterion-cpu-time", + "move-binary-format", + "move-compiler", + "move-core-types", + "move-stdlib", + "move-vm-runtime", + "move-vm-test-utils", + "move-vm-types", + "once_cell", +] + +[[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.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb09950ae85a0a94b27676cccf37da5ff13f27076aa1adbc6545dd0d0e1bd4e" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "libm" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "libtest-mimic" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79529479c298f5af41375b0c1a77ef670d450b4c9cd7949d2b43af08121b20ec" +dependencies = [ + "clap 3.2.23", + "termcolor", + "threadpool", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", + "serde", +] + +[[package]] +name = "lsp-server" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c351c75989da23b355226dc188dc2b52538a7f4f218d70fd7393c6b62b110444" +dependencies = [ + "crossbeam-channel", + "log", + "serde", + "serde_json", +] + +[[package]] +name = "lsp-types" +version = "0.90.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f3734ab1d7d157fc0c45110e06b587c31cd82bea2ccfd6b563cbff0aaeeb1d3" +dependencies = [ + "bitflags", + "serde", + "serde_json", + "serde_repr", + "url", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memory-stats" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34f79cf9964c5c9545493acda1263f1912f8d2c56c8a2ffee2606cb960acaacc" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "mio" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.45.0", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "module-generation" +version = "0.1.0" +dependencies = [ + "move-binary-format", + "move-bytecode-verifier", + "move-core-types", + "move-ir-to-bytecode", + "move-ir-types", + "move-symbol-pool", + "rand 0.8.5", +] + +[[package]] +name = "move-abigen" +version = "0.1.0" +dependencies = [ + "anyhow", + "bcs", + "codespan-reporting", + "datatest-stable", + "heck 0.3.3", + "log", + "move-binary-format", + "move-bytecode-verifier", + "move-command-line-common", + "move-core-types", + "move-model", + "move-prover", + "move-prover-test-utils", + "serde", + "tempfile", +] + +[[package]] +name = "move-abstract-stack" +version = "0.0.1" + +[[package]] +name = "move-analyzer" +version = "1.0.0" +dependencies = [ + "anyhow", + "clap 4.4.1", + "codespan-reporting", + "crossbeam", + "derivative", + "dunce", + "im", + "lsp-server", + "lsp-types", + "move-command-line-common", + "move-compiler", + "move-ir-types", + "move-package", + "move-symbol-pool", + "serde_json", + "tempfile", + "url", +] + +[[package]] +name = "move-binary-format" +version = "0.0.3" +dependencies = [ + "anyhow", + "arbitrary", + "enum-compat-util", + "getrandom 0.2.9", + "move-core-types", + "move-proc-macros", + "proptest", + "proptest-derive", + "ref-cast", + "serde", + "serde_json", + "variant_count", +] + +[[package]] +name = "move-borrow-graph" +version = "0.0.1" + +[[package]] +name = "move-bytecode-source-map" +version = "0.1.0" +dependencies = [ + "anyhow", + "bcs", + "move-binary-format", + "move-command-line-common", + "move-core-types", + "move-ir-types", + "move-symbol-pool", + "serde", +] + +[[package]] +name = "move-bytecode-utils" +version = "0.1.0" +dependencies = [ + "anyhow", + "move-binary-format", + "move-core-types", + "petgraph", + "serde-reflection", +] + +[[package]] +name = "move-bytecode-verifier" +version = "0.1.0" +dependencies = [ + "hex-literal", + "invalid-mutations", + "move-abstract-stack", + "move-binary-format", + "move-borrow-graph", + "move-core-types", + "move-vm-config", + "petgraph", +] + +[[package]] +name = "move-bytecode-viewer" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.4.1", + "crossterm 0.21.0", + "move-binary-format", + "move-bytecode-source-map", + "move-disassembler", + "regex", + "tui", +] + +[[package]] +name = "move-cli" +version = "0.1.0" +dependencies = [ + "anyhow", + "bcs", + "clap 4.4.1", + "codespan-reporting", + "colored", + "datatest-stable", + "difference", + "move-binary-format", + "move-bytecode-utils", + "move-bytecode-verifier", + "move-bytecode-viewer", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-coverage", + "move-disassembler", + "move-docgen", + "move-errmapgen", + "move-ir-types", + "move-package", + "move-prover", + "move-read-write-set-types", + "move-stdlib", + "move-unit-test", + "move-vm-profiler", + "move-vm-runtime", + "move-vm-test-utils", + "move-vm-types", + "serde_yaml", + "tempfile", + "toml_edit 0.14.4", + "walkdir", +] + +[[package]] +name = "move-command-line-common" +version = "0.1.0" +dependencies = [ + "anyhow", + "difference", + "dirs-next", + "hex", + "move-core-types", + "num-bigint", + "once_cell", + "serde", + "sha2 0.9.9", + "walkdir", +] + +[[package]] +name = "move-compiler" +version = "0.0.1" +dependencies = [ + "anyhow", + "bcs", + "clap 4.4.1", + "codespan-reporting", + "datatest-stable", + "hex", + "move-binary-format", + "move-borrow-graph", + "move-bytecode-source-map", + "move-bytecode-verifier", + "move-command-line-common", + "move-core-types", + "move-ir-to-bytecode", + "move-ir-types", + "move-stdlib", + "move-symbol-pool", + "once_cell", + "petgraph", + "regex", + "serde", + "tempfile", +] + +[[package]] +name = "move-compiler-transactional-tests" +version = "0.1.0" +dependencies = [ + "datatest-stable", + "move-transactional-test-runner", +] + +[[package]] +name = "move-core-types" +version = "0.0.4" +dependencies = [ + "anyhow", + "arbitrary", + "bcs", + "enum-compat-util", + "ethnum", + "hex", + "move-proc-macros", + "num", + "once_cell", + "primitive-types", + "proptest", + "proptest-derive", + "rand 0.8.5", + "ref-cast", + "regex", + "serde", + "serde_bytes", + "serde_json", + "uint", +] + +[[package]] +name = "move-coverage" +version = "0.1.0" +dependencies = [ + "anyhow", + "bcs", + "clap 4.4.1", + "codespan", + "colored", + "move-binary-format", + "move-bytecode-source-map", + "move-command-line-common", + "move-core-types", + "move-ir-types", + "petgraph", + "serde", +] + +[[package]] +name = "move-disassembler" +version = "0.1.0" +dependencies = [ + "anyhow", + "bcs", + "clap 4.4.1", + "colored", + "hex", + "move-binary-format", + "move-bytecode-source-map", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-coverage", + "move-ir-types", +] + +[[package]] +name = "move-docgen" +version = "0.1.0" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "datatest-stable", + "itertools", + "log", + "move-compiler", + "move-model", + "move-prover", + "move-prover-test-utils", + "num", + "once_cell", + "regex", + "serde", + "tempfile", +] + +[[package]] +name = "move-errmapgen" +version = "0.1.0" +dependencies = [ + "anyhow", + "codespan-reporting", + "datatest-stable", + "move-command-line-common", + "move-core-types", + "move-model", + "move-prover", + "serde", +] + +[[package]] +name = "move-explain" +version = "0.1.0" +dependencies = [ + "bcs", + "clap 4.4.1", + "move-command-line-common", + "move-core-types", +] + +[[package]] +name = "move-ir-compiler" +version = "0.1.0" +dependencies = [ + "anyhow", + "bcs", + "clap 4.4.1", + "move-binary-format", + "move-bytecode-source-map", + "move-bytecode-verifier", + "move-command-line-common", + "move-ir-to-bytecode", + "serde_json", +] + +[[package]] +name = "move-ir-compiler-transactional-tests" +version = "0.1.0" +dependencies = [ + "datatest-stable", + "move-transactional-test-runner", +] + +[[package]] +name = "move-ir-to-bytecode" +version = "0.1.0" +dependencies = [ + "anyhow", + "codespan-reporting", + "log", + "move-binary-format", + "move-bytecode-source-map", + "move-command-line-common", + "move-core-types", + "move-ir-to-bytecode-syntax", + "move-ir-types", + "move-symbol-pool", + "ouroboros", +] + +[[package]] +name = "move-ir-to-bytecode-syntax" +version = "0.1.0" +dependencies = [ + "anyhow", + "hex", + "move-command-line-common", + "move-core-types", + "move-ir-types", + "move-symbol-pool", +] + +[[package]] +name = "move-ir-types" +version = "0.1.0" +dependencies = [ + "hex", + "move-command-line-common", + "move-core-types", + "move-symbol-pool", + "once_cell", + "serde", +] + +[[package]] +name = "move-model" +version = "0.1.0" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "datatest-stable", + "internment", + "itertools", + "log", + "move-binary-format", + "move-bytecode-source-map", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-disassembler", + "move-ir-types", + "move-prover-test-utils", + "move-symbol-pool", + "num", + "once_cell", + "regex", + "serde", +] + +[[package]] +name = "move-package" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.4.1", + "colored", + "datatest-stable", + "move-abigen", + "move-binary-format", + "move-bytecode-source-map", + "move-bytecode-utils", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-docgen", + "move-model", + "move-symbol-pool", + "named-lock", + "once_cell", + "petgraph", + "regex", + "serde", + "serde_yaml", + "sha2 0.9.9", + "tempfile", + "toml", + "treeline", + "walkdir", + "whoami", +] + +[[package]] +name = "move-proc-macros" +version = "0.1.0" +dependencies = [ + "enum-compat-util", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "move-prover" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.4.1", + "codespan-reporting", + "datatest-stable", + "itertools", + "log", + "move-abigen", + "move-command-line-common", + "move-compiler", + "move-docgen", + "move-errmapgen", + "move-model", + "move-prover-boogie-backend", + "move-prover-test-utils", + "move-stackless-bytecode", + "once_cell", + "serde", + "shell-words", + "simplelog", + "tempfile", + "toml", + "walkdir", +] + +[[package]] +name = "move-prover-boogie-backend" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "codespan", + "codespan-reporting", + "futures", + "itertools", + "log", + "move-binary-format", + "move-command-line-common", + "move-core-types", + "move-model", + "move-stackless-bytecode", + "num", + "once_cell", + "pretty", + "rand 0.8.5", + "regex", + "serde", + "tera", + "tokio", +] + +[[package]] +name = "move-prover-test-utils" +version = "0.1.0" +dependencies = [ + "anyhow", + "move-command-line-common", + "prettydiff", + "regex", +] + +[[package]] +name = "move-read-write-set-types" +version = "0.0.3" +dependencies = [ + "move-binary-format", + "move-core-types", + "serde", +] + +[[package]] +name = "move-stackless-bytecode" +version = "0.1.0" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "datatest-stable", + "ethnum", + "im", + "itertools", + "log", + "move-binary-format", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-model", + "move-prover-test-utils", + "move-read-write-set-types", + "move-stdlib", + "num", + "paste", + "petgraph", + "serde", +] + +[[package]] +name = "move-stackless-bytecode-interpreter" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytecode-interpreter-crypto", + "clap 4.4.1", + "codespan-reporting", + "datatest-stable", + "itertools", + "move-binary-format", + "move-core-types", + "move-model", + "move-prover-test-utils", + "move-stackless-bytecode", + "num", +] + +[[package]] +name = "move-stdlib" +version = "0.1.1" +dependencies = [ + "anyhow", + "dir-diff", + "file_diff", + "hex", + "log", + "move-binary-format", + "move-cli", + "move-command-line-common", + "move-core-types", + "move-docgen", + "move-errmapgen", + "move-package", + "move-prover", + "move-unit-test", + "move-vm-runtime", + "move-vm-types", + "sha2 0.9.9", + "sha3", + "smallvec", + "tempfile", + "walkdir", +] + +[[package]] +name = "move-symbol-pool" +version = "0.1.0" +dependencies = [ + "once_cell", + "phf", + "serde", + "serde_json", +] + +[[package]] +name = "move-transactional-test-runner" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "clap 4.4.1", + "datatest-stable", + "difference", + "move-binary-format", + "move-bytecode-source-map", + "move-cli", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-disassembler", + "move-ir-compiler", + "move-ir-types", + "move-stdlib", + "move-symbol-pool", + "move-vm-config", + "move-vm-runtime", + "move-vm-test-utils", + "move-vm-types", + "once_cell", + "rayon", + "regex", + "tempfile", + "tokio", +] + +[[package]] +name = "move-unit-test" +version = "0.1.0" +dependencies = [ + "anyhow", + "better_any", + "clap 4.4.1", + "codespan-reporting", + "colored", + "datatest-stable", + "difference", + "itertools", + "move-binary-format", + "move-bytecode-utils", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-ir-types", + "move-model", + "move-stackless-bytecode-interpreter", + "move-stdlib", + "move-symbol-pool", + "move-vm-profiler", + "move-vm-runtime", + "move-vm-test-utils", + "move-vm-types", + "once_cell", + "rayon", + "regex", +] + +[[package]] +name = "move-vm-config" +version = "0.1.0" +dependencies = [ + "move-binary-format", +] + +[[package]] +name = "move-vm-integration-tests" +version = "0.1.0" +dependencies = [ + "anyhow", + "fail", + "memory-stats", + "move-binary-format", + "move-bytecode-verifier", + "move-compiler", + "move-core-types", + "move-stdlib", + "move-vm-config", + "move-vm-profiler", + "move-vm-runtime", + "move-vm-test-utils", + "move-vm-types", + "tempfile", +] + +[[package]] +name = "move-vm-profiler" +version = "0.1.0" +dependencies = [ + "move-vm-config", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "move-vm-runtime" +version = "0.1.0" +dependencies = [ + "anyhow", + "better_any", + "fail", + "hex", + "move-binary-format", + "move-bytecode-verifier", + "move-compiler", + "move-core-types", + "move-ir-compiler", + "move-vm-config", + "move-vm-profiler", + "move-vm-types", + "once_cell", + "parking_lot 0.11.2", + "proptest", + "sha3", + "smallvec", + "tracing", +] + +[[package]] +name = "move-vm-test-utils" +version = "0.1.0" +dependencies = [ + "anyhow", + "move-binary-format", + "move-core-types", + "move-vm-profiler", + "move-vm-types", + "once_cell", + "serde", +] + +[[package]] +name = "move-vm-transactional-tests" +version = "0.1.0" +dependencies = [ + "datatest-stable", + "move-transactional-test-runner", +] + +[[package]] +name = "move-vm-types" +version = "0.1.0" +dependencies = [ + "bcs", + "move-binary-format", + "move-core-types", + "move-vm-profiler", + "proptest", + "serde", + "smallvec", +] + +[[package]] +name = "named-lock" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a3eb6b7c682b65d1f631ec3176829d72ab450b3aacdd3f719bf220822e59ac" +dependencies = [ + "libc", + "once_cell", + "parking_lot 0.12.1", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "ntapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +dependencies = [ + "winapi", +] + +[[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" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "os_str_bytes" +version = "6.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" + +[[package]] +name = "ouroboros" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parity-scale-codec" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +dependencies = [ + "arrayvec 0.7.2", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[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 0.9.7", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pest" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1403e8401ad5dedea73c626b99758535b342502f8d1e361f4a2dd952749122" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be99c4c1d2fc2769b1d00239431d711d08f6efedcecb8b6e30707160aee99c15" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e56094789873daa36164de2e822b3888c6ae4b4f9da555a1103587658c805b1e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "pest_meta" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6733073c7cff3d8459fda0e42f13a047870242aed8b509fe98000928975f359e" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.6", +] + +[[package]] +name = "petgraph" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", + "uncased", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "plotters" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" + +[[package]] +name = "plotters-svg" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9940b913ee56ddd94aec2d3cd179dd47068236f42a1a6415ccf9d880ce2a61" +dependencies = [ + "arrayvec 0.5.2", + "typed-arena", +] + +[[package]] +name = "prettydiff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bc9e8bdfe446d34975ff774fbb4a2b944d17054f6b5845ec132d4fb9ff8f559" +dependencies = [ + "ansi_term 0.9.0", + "prettytable-rs", + "structopt", +] + +[[package]] +name = "prettytable-rs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" +dependencies = [ + "atty", + "csv", + "encode_unicode", + "lazy_static", + "term", + "unicode-width", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.8", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc-macro2" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f1b898011ce9595050a68e60f90bad083ff2987a695a42357134c8381fba70" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "proptest-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90b46295382dc76166cb7cf2bb4a97952464e4b7ed5a43e6cd34e1fec3349ddc" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "prover-mutation" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.4.1", + "codespan-reporting", + "itertools", + "log", + "move-compiler", + "move-model", + "move-prover", + "move-stackless-bytecode", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2 1.0.63", +] + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[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" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.9", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom 0.1.16", + "redox_syscall 0.1.57", + "rust-argon2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.9", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "ref-cast" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43faa91b1c8b36841ee70e97188a869d37ae21759da6846d4be66de5bf7b12c" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "regex" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustix" +version = "0.37.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", +] + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[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 = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + +[[package]] +name = "serde" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-reflection" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05a5f801ac62a51a49d378fdb3884480041b99aced450b28990673e8ff99895" +dependencies = [ + "once_cell", + "serde", + "thiserror", +] + +[[package]] +name = "serde_bytes" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "serde_json" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[package]] +name = "serde_yaml" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "serializer-tests" +version = "0.1.0" +dependencies = [ + "move-binary-format", + "proptest", + "proptest-derive", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "signal-hook" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio 0.7.14", + "signal-hook", +] + +[[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 = "simplelog" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bc0ffd69814a9b251d43afcabf96dad1b29f5028378056257be9e3fecc9f720" +dependencies = [ + "chrono", + "log", + "termcolor", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slug" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" +dependencies = [ + "deunicode", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spec-flatten" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.4.1", + "itertools", + "move-compiler", + "move-model", + "move-prover", + "move-stackless-bytecode", + "pretty", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "structopt" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" +dependencies = [ + "clap 2.34.0", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" +dependencies = [ + "heck 0.3.3", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", +] + +[[package]] +name = "tera" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df578c295f9ec044ff1c829daf31bb7581d5b3c2a7a3d87419afe1f2531438c" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand 0.8.5", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "term" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +dependencies = [ + "byteorder", + "dirs", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test-generation" +version = "0.1.0" +dependencies = [ + "clap 4.4.1", + "crossbeam-channel", + "getrandom 0.2.9", + "hex", + "itertools", + "module-generation", + "move-binary-format", + "move-bytecode-verifier", + "move-compiler", + "move-core-types", + "move-stdlib", + "move-vm-runtime", + "move-vm-test-utils", + "move-vm-types", + "num_cpus", + "once_cell", + "rand 0.8.5", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[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", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio 0.8.6", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" + +[[package]] +name = "toml_edit" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f" +dependencies = [ + "combine", + "indexmap", + "itertools", + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "treeline" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" + +[[package]] +name = "tui" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ed0a32c88b039b73f1b6c5acbd0554bfa5b6be94467375fd947c4de3a02271" +dependencies = [ + "bitflags", + "cassowary", + "crossterm 0.22.1", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "uncased" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" +dependencies = [ + "version_check", +] + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8parse" +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 = "variant_count" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" +dependencies = [ + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[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.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote 1.0.28", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whoami" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", +] diff --git a/vendors/move/Cargo.toml b/vendors/move/Cargo.toml new file mode 100644 index 000000000..47c9eeb72 --- /dev/null +++ b/vendors/move/Cargo.toml @@ -0,0 +1,171 @@ +[workspace] +resolver = "2" + +members = [ + "crates/*", +] + +# Dependencies that should be kept in sync through the whole workspace +[workspace.dependencies] +aes-gcm = "0.8.0" +anyhow = "1.0.52" +arbitrary = { version = "1.1.7", features = ["derive", "derive_arbitrary"] } +async-trait = "0.1.42" +bcs = "0.1.4" +better_any = "0.1.1" +bitvec = "0.19.4" +byteorder = "1.4.3" +bytes = "1.0.1" +chrono = "0.4.19" +clap = { version = "4", features = ["derive"] } +codespan = "0.11.1" +codespan-reporting = "0.11.1" +colored = "2.0.0" +criterion = "0.3.4" +criterion-cpu-time = "0.1.0" +crossbeam = "0.8" +crossbeam-channel = "0.5.0" +crossterm = "0.21" +curve25519-dalek = { version = "0.1.0", package = "curve25519-dalek-fiat", default-features = false, features = ["std", "u64_backend"] } +datatest-stable = "0.1.1" +derivative = "2.2.0" +difference = "2.0.0" +digest = "0.9.0" +dir-diff = "0.3.2" +dirs-next = "2.0.0" +dunce = "1.0.2" +ed25519-dalek = { version = "0.1.0", package = "ed25519-dalek-fiat", default-features = false, features = ["std", "serde", "u64_backend"] } +ethnum = "1.0.4" +fail = "0.4.0" +file_diff = "1.0.0" +futures = "0.3.12" +getrandom = "0.2.9" +heck = "0.3.2" +hex = "0.4.3" +hex-literal = "0.3.4" +hkdf = "0.10.0" +im = "15.1.0" +internment = { version = "0.5.0", features = [ "arc"] } +itertools = "0.10.0" +libfuzzer-sys = "0.4" +log = { version = "0.4.14", features = ["serde"] } +lsp-server = "0.5.1" +lsp-types = "0.90.1" +memory-stats = "1.0.0" +mirai-annotations = "1.10.1" +named-lock = "0.2.0" +num = "0.4.0" +num-bigint = "0.4.0" +num_cpus = "1.13.0" +once_cell = "1.7.2" +ouroboros = "0.17.2" +parking_lot = "0.11.1" +paste = "1.0.5" +petgraph = "0.5.1" +phf = { version = "0.11", features = ["macros"] } +plotters = { version = "0.3.0", default_features = false, features = ["evcxr", "line_series", "histogram"]} +pretty = "0.10.0" +prettydiff = "0.4.0" +primitive-types = { version = "0.10.1", features = ["impl-serde"]} +proc-macro2 = "1.0.24" +proptest = "1.0.0" +proptest-derive = "0.3.0" +quote = "1.0.9" +rand = "0.8.0" +rayon = "1.5.0" +ref-cast = "1.0.6" +regex = "1.5.5" +ripemd160 = "0.9.1" +serde = { version = "1.0.124", features = ["derive"] } +serde-name = "0.1.1" +serde-reflection = "0.3.2" +serde_bytes = "0.11.5" +serde_json = "1.0.64" +serde_yaml = "0.8.26" +sha2 = "0.9.3" +sha3 = "0.9.1" +shell-words = "1.0.0" +simplelog = "0.9.0" +smallvec = "1.6.1" +static_assertions = "1.1.0" +syn = { version = "1.0.64", features = ["derive"] } +tempfile = "3.2.0" +tera = "1.16.0" +thiserror = "1.0.24" +tiny-keccak = { version = "2.0.2", features = ["sha3"] } +tokio = { version = "1.18.2", features = ["full"] } +toml = "0.5.8" +toml_edit = { version = "0.14.3", features = ["easy"] } +tracing = "0.1.26" +tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } +treeline = "0.1.0" +tui = "0.17.0" +uint = "0.9.4" +url = "2.2.2" +variant_count = "1.1.0" +walkdir = "2.3.1" +whoami = { version = "1.2.1" } +x25519-dalek = { version = "0.1.0", package = "x25519-dalek-fiat", default-features = false, features = ["std", "u64_backend"] } +z3tracer = "0.8.0" + +bytecode-interpreter-crypto = { path = "crates/bytecode-interpreter-crypto" } +enum-compat-util = { path = "crates/enum-compat-util"} +invalid-mutations = { path = "crates/invalid-mutations" } +module-generation = { path = "crates/module-generation" } +move-abigen = { path = "crates/move-abigen" } +move-abstract-stack = { path = "crates/move-abstract-stack" } +move-binary-format = { path = "crates/move-binary-format" } +move-borrow-graph = { path = "crates/move-borrow-graph" } +move-bytecode-source-map = { path = "crates/move-bytecode-source-map" } +move-bytecode-utils = { path = "crates/move-bytecode-utils" } +move-bytecode-verifier = { path = "crates/move-bytecode-verifier" } +move-bytecode-viewer = { path = "crates/move-bytecode-viewer" } +move-cli = { path = "crates/move-cli" } +move-command-line-common = { path = "crates/move-command-line-common" } +move-compiler = { path = "crates/move-compiler" } +move-core-types = { path = "crates/move-core-types" } +move-coverage = { path = "crates/move-coverage" } +move-disassembler = { path = "crates/move-disassembler" } +move-docgen = { path = "crates/move-docgen" } +move-errmapgen = { path = "crates/move-errmapgen" } +move-ir-compiler = { path = "crates/move-ir-compiler" } +move-ir-to-bytecode = { path = "crates/move-ir-to-bytecode" } +move-ir-to-bytecode-syntax = { path = "crates/move-ir-to-bytecode-syntax" } +move-ir-types = { path = "crates/move-ir-types" } +move-model = { path = "crates/move-model" } +move-package = { path = "crates/move-package" } +move-proc-macros = { path = "crates/move-proc-macros"} +move-prover = { path = "crates/move-prover" } +move-prover-boogie-backend = { path = "crates/move-prover-boogie-backend" } +move-prover-test-utils = { path = "crates/move-prover-test-utils" } +move-read-write-set-types = { path = "crates/move-read-write-set-types" } +move-stackless-bytecode = { path = "crates/move-stackless-bytecode" } +move-stackless-bytecode-interpreter = { path = "crates/move-stackless-bytecode-interpreter" } +move-stdlib = { path = "crates/move-stdlib" } +move-symbol-pool = { path = "crates/move-symbol-pool" } +move-transactional-test-runner = { path = "crates/move-transactional-test-runner" } +move-unit-test = { path = "crates/move-unit-test" } +move-vm-config = { path = "crates/move-vm-config" } +move-vm-profiler = { path = "crates/move-vm-profiler" } +move-vm-runtime = { path = "crates/move-vm-runtime" } +move-vm-test-utils = { path = "crates/move-vm-test-utils" } +move-vm-types = { path = "crates/move-vm-types" } +prover_bytecode = { path = "crates/move-stackless-bytecode", package="move-stackless-bytecode" } + +[profile.bench] +debug = true + +[profile.dev] +debug = true + +[profile.test.package.move-vm-integration-tests] +# opt-level 2 for move-compiler reduces the size of some of its +# (recursive) stack frames by up to 10x, avoiding stack overflows. +opt-level = 3 + +# use release settings to reduce memory pressure in the linking step in CI +[profile.ci] +inherits = "test" +debug = 0 # for saving disk space during linking +incremental = false +codegen-units = 16 diff --git a/vendors/move/README.md b/vendors/move/README.md new file mode 100644 index 000000000..0acf524c9 --- /dev/null +++ b/vendors/move/README.md @@ -0,0 +1,24 @@ +--- +id: move-language +title: Move Language +custom_edit_url: https://github.com/move-language/move/edit/main/language/README.md +--- + + +Move is a new programming language developed to provide a safe and programmable foundation for the Diem Blockchain. + +## Overview + +The Move language directory consists of four main parts: + +- [virtual machine](move-vm/) (VM) — contains the bytecode format, a bytecode interpreter, and infrastructure for executing a block of transactions. This directory also contains the infrastructure to generate the genesis block. + +- [bytecode verifier](move-bytecode-verifier/) — contains a static analysis tool for rejecting invalid Move bytecode. The virtual machine runs the bytecode verifier on any new Move code it encounters before executing it. The compiler runs the bytecode verifier on its output and surfaces the errors to the programmer. + +- [move-compiler](move-compiler/) — contains the Move source language compiler. + +- [standard library](move-stdlib/) — contains the standard library transaction scripts. + +## Exploring the Move language + +- You can find many small Move examples in the [tests](move-compiler/tests/move_check/) directory. The easiest way to experiment with Move is to create a new test in this directory and run it with `cargo test`. diff --git a/vendors/move/changes/1-friend-visibility.md b/vendors/move/changes/1-friend-visibility.md new file mode 100644 index 000000000..4ce2dfa3e --- /dev/null +++ b/vendors/move/changes/1-friend-visibility.md @@ -0,0 +1,195 @@ +# Friend Visibility + +* Status: Implemented in Move 1.2 + +## Introduction + +Friend visibility is a new feature in Move version 1.2 to give more control about where a function can be used. Previously a function had either public or private visibility, where a public function is accessible anywhere but a private function can be called only from within the module where it is defined. Friend-visible functions can be called only from explicitly allowed modules. + +## Motivations + +### Overly Permissive Function Visibility Model + +The simple public/private visibility scheme required using public visibility for “limited-access” functions, i.e., functions that: + +* are designed to have limited access by a known and specific set of modules only (i.e., an allowlist), and +* should not be accessed by any other modules outside this specific allowlist. + +Take all the `initialize` functions in the Diem framework as an example. In theory, the `initialize` functions should only be used by the `Genesis` module and never be exposed to any other modules nor scripts. However, due to the limitation in the current visibility model, these `initialize` functions have to be made `public` (in order for the `Genesis` module to call them) and both runtime capability checks and static verification are enforced to make sure that these functions will abort if not called from a genesis state. + +### Inflexibility in Future Module Updates + +Public functions have very restricted updating rules: a public function can never be deleted or renamed, and its function signature can never be altered. The rationale behind this restriction is that a public function is a contract made to the whole world and once the contract is made, the API should not be easily altered, as altering the API might break code that tries to invoke the public function. The owner of the public function has no control on who can invoke the function. In fact, knowing all the call sites requires a global scan of all code published in storage, which is not always possible nor scalable in a blockchain network with an open-publishing model. + +In contrast, a friend function is only a contract made to the friends of a module, and furthermore, the module owner controls the membership of the friend list. That is, the module owner has complete knowledge of which modules may access a friend function. As a result, it is much easier to update a friend function because only the modules in the friend list needs to be coordinated for the change. This is especially true when a friend function and all its friend modules are maintained by the same owner. + +### Simplification Opportunities for Specification and Verification + +Friend visibility can help simplify specification writing and verification with the Move prover. For example, given a friend function and its host module’s friend list, we can easily and exhaustively find all callsites of the friend function. With this information, we could, as an option, completely skip the specification of a friend function and inline the implementation into the caller. This may lead to further simplification in the verification techniques and allows stronger properties to be proved. In contrast, for a public function, it is necessary to write complete and accurate specifications for the function. + +## Description + +Friend visibility expands the set of possible visibility levels: + +* private (no modifier) +* `public(friend)` +* `public(script)`, and +* `public`. + +These respectively correspond to `Private`, `Friend`, `Script`, and `Public` in the Move bytecode file format. Script visibility addresses an orthogonal problem in the Diem Framework and more details can be found in the [Script Visibility](2-script-visibility.md) change description. + +Beside the new `public(friend)` modifier, each module is allowed to have a friend list, specifiable as zero or more +`friend ` statements that list the modules trusted by the host module. Modules in the friend list are permitted to call a `public(friend)` function defined in the host module, but a non-friend module is prohibited from accessing a `public(friend)` function. + +### New Visibility Modifier + +`public(friend)` is a new visibility modifier that can be applied to any function definition in a module. A `public(friend)` function can be invoked by any other functions in the same module (say module `M`), or any function defined in one of the modules in the friend list of module `M`. + +Besides this visibility rule, `public(friend)` functions follow the same rules as any other module function, meaning they can invoke other functions in the same module (except `public(script)` functions), create new struct instances, access the global storage (of types declared in that module), etc. + +### Friend List Declarations + +A module can declare other modules as friends via friend declaration statements, in the format of + +* `friend ` — friend declaration using fully qualified module name +* `friend ` — friend declaration using a module name alias, where the module alias is introduced via the `use` statement. + +A module may have multiple friend declarations, and the union of all the friend modules is recorded in the friend list, which is a new section in the bytecode file format. For readability, friend declarations should generally be placed near the beginning of the module definition. Note that Move scripts cannot declare friend modules as the concept of friend functions does not even exist in scripts. + +Friend declarations are subject to the following rules: + +* A module cannot declare itself as a friend. + * e.g., `0x2::M` cannot declare `0x2::M` as a friend. +* Friend modules must be within the same account address. + * e.g., `0x2::M` cannot declare `0x3::N` as a friend. + * Note: this is not a technical requirement but rather a policy decision which may be relaxed later. +* Friends relationships cannot create cyclic module dependencies. + * Cycles are not allowed in the friend relationships. E.g., `0x2::A` friends `0x2::B` friends `0x2::C` friends `0x2::A` is not allowed. + * More generally, declaring a friend module adds a dependency upon the current module to the friend module (because the purpose is for the friend to call functions in the current module). If that friend module is already used, either directly or transitively, a cycle of dependencies would be created. E.g., a cycle would be created if `0x2::A` friends `0x2::B` and `0x2::A` also calls a function `0x2::B::foo().` +* Friends must exist when the module is published. + * e.g., `0x2::M` cannot declare `0x2::X` as a friend if `0x2::X` cannot be resolved by the loader. +* The friend list for a module cannot contain duplicates. + +## Examples + +A typical module with `public(friend)` functions and its friend modules is shown in the following example: + +``` +address 0x2 { + module A { + // friend declaration via fully qualified module name + friend 0x2::B; + + // friend declaration via module alias + use 0x2::C; + friend C; + + public(friend) fun foo() { + // a friend function can call other non-script functions in the same module + i_am_private(); + i_am_public(); + bar(); + } + public(friend) fun bar() {} + + fun i_am_private() { + // other functions in the same module can also call friend functions + bar(); + } + public fun i_am_public() { + // other functions in the same module can also call friend functions + bar(); + } + } + + module B { + use 0x2::A; + + public fun foo() { + // as a friend of 0x2::A, functions in B can call friend functions in A + A::foo(); + } + + public fun bar() { + 0x2::A::bar(); + } + } +} +``` + +## Alternatives + +### Granularity of the Friend List + +* Module-to-Module (adopted) + * Module `B` is a friend of module `A` — any function in module `B` can access any friend function in module `A` + * Modules have been the trust boundary in Move language, as evidenced by: + * the existing visibility model where public and private are defined with regard to the hosting module of a particular function; + * the design of Struct / Resource type where only the module that defines the Struct / Resource may access the internals of the type. + * Therefore, it is more natural for modules to be the trust boundary of friend function accesses as well. + * Another reason is that it resonates with the granularity of the friend feature found in other languages (e.g., C++). +* Module-to-Function + * Module `B` is a friend of function `foo()` — any function in module `B` can call the friend function `foo()` + * This is a more fine-grained version of Module-to-Module friendship declaration and is also found in other languages (e.g., C++ also supports Module-to-Function friendship). The reasons we did not choose this option are mostly 1) it breaks the mental model that modules are the boundaries in Move, and 2) it may lead to the case where a module (e.g., module `A`) is a friend of every friend function and `friend A` needs to be specified repeatedly for each friend function. +* Function-to-Module + * Function `foo()` is a friend of module `A` — function `foo()` can call any friend function in module `A` + * The reason this option is not chosen is because it seems weird to express, as a developer, that we trust function `0x3::B::foo()` but not function `0x3::B::bar()`, especially given that both `bar()` and `foo()` reside in the same module by `0x3::B`. We could not contemplate a valid use case for this scenario. +* Function-to-Function + * Function `foo()` is a friend of function `bar()` — function `foo()` can call friend function `bar()` + * Besides the reason that it feels weird trusting one function in a module but not another (similar to the Function-to-Module option), we feel that this scheme is too fine-grained and would cause inflexibility in development, especially on function name updates. To illustrate, suppose `foo()` is a private function in module `B`, and `bar()` is a friend function in module `A`. This scheme requires that when the private function `foo` is renamed, something in module A needs to be updated as well! Function `foo()` is no longer “private” to module `B` under this scheme. + +### Location of Friend Declarations + +* Callee-side declaration (adopted) + * The code owner who develops the module is responsible for specifying who can be a friend of this module at the time of writing the source code. If later the developers want to add / remove new friends, they can always update the friend list and re-publish the module on-chain (subject to updatability and compatibility checking). + * This is the most natural way of defining the friend list, since the friend list is embedded the same source file as the module source code. Compared with the alternative — caller-side declaration — it is cognitively easier for developers to figure out who may interact with the friend functions and how the friend functions should be hardened by looking within the same file. +* Caller-side declaration + * An alternative thinking is to have the user of a friend function to “request” friendship permission, instead of having the owner of the friend function to “grant” friendship. To illustrate, if module `B` wants to access some friend functions in module `A`, then, the friendship with module `A` will be declared in the source code of module `B` (while the callee-side declaration requires that the friendship is declared in the source code of module `A`). + * A major drawback in this alternative is that the code owner does not have a list of friend relationships if the developers do not actively maintain one. For friend relationships, the source of truth is likely to be stored on-chain either via 1) a VM-updatable section in on-chain module bytecode, or 2) a new `FriendList` entity in users’ accounts. More importantly, by looking at the source code of a module, the developers have no clue who can access the friend function and how the interaction may happen. + +### Publishing Order + +Cross-module references complicate the process for publishing those modules. The issue can be illustrated in the following: + +``` +address 0x2 { + module M { + friend 0x2::N; + public(friend) fun foo() {} + } + module N { + use 0x2::M; + fun bar() { M::foo(); } + } +} +``` + +Suppose we define two modules `M` and `N` like the above: + +* Module `N` depends on `M` because `N` contains `use 0x2::M` +* But, at the same time, module `M` refers to `N` because `M` specifies `friend 0x2::N` + +Now think about how we should publish them on-chain.... + +* With the current one-module-at-a-time publishing model: + * Obviously module `M` has to be published first. Otherwise, publishing module `N` first will make `N::bar()` fail miserably, while publishing `M` first should have no bad effects because no one can call `M::foo()` anyway. + * But, when publishing `M`, the bytecode verifier sees the visibility constraint, and it is a pointer to a nonexistent function `N::bar()`. The bytecode verifier will *not* try to resolve this function handle. It *must* tolerate that this visibility constraint is a forward declaration. + * A risk associated with the above procedure is the possibility of a race condition when publishing module `N`. Suppose both Alice and Eve can publish to `0x2`. When `M` is published, both Alice and Eve see that `M` declares `N` as a friend. Eve may race against Alice to publish module `N` first, with a bad `bar()` function, to exploit the trust the developer of module `M` placed on Alice. + * A solution to this problem is enforcing a safer but more convoluted module publication flow that still uses the one-module-at-a-time publishing model. For the example above, the flow would require three steps: + * publish an empty module `N` as a place holder + * publish module `M` + * publish the updated module `N` that uses the friend function `M` +* With a future multi-signer, multi-module publication model: + * To avoid a convoluted module publishing flow, another solution is to use a multi-signer + multi-module publication model that allows a bundle of modules to be published / updated atomically, even if these modules reside in different user accounts. In the above case, if we could publish `M` and `N` atomically in one transaction, there would be no risk of a race condition and there is no need to go through the three-step module publishing flow. + +### Other Schemes for “Shared” Visibility + +* Address visibility + * Java uses a “package” concept that maps to a given location (namespace) which could roughly be thought of as an address (the address the modules are published under). Addresses in Move could serve the role of “package” in Java. With that approach, we could do something like `public(address)` — or just `internal` — that would allow for cross module visibility, but just under that address. The owner of that address would control all publishing into that address. This kind of visibility would be easy to enforce by a verifier given the address constraints. That is, the target function when linking would have to be in a module published under the same address. + * The problem with this model is that we have no way to control subsequent publishing into that address, which could violate the principle in Move that all bindings are known when one publishes and they cannot be altered. If publishing under the same address gave someone access to the internal state of other modules it would be possible to read and alter state that was originally intended to be private to a group of modules. +* Package visibility + * This is the the .NET CLR model of “internal” visibility, i.e., things that get compiled together can access each other's internal state based merely on the fact that they are compiled together. In Move, “compiled together” really means published together, so a bundle would require a change in publishing (and the module publish transaction) that would have to accept a list of modules rather than a single one. That would give the verifier a chance to control access across modules. That is, cross module calls towards internal visibility would be allowed if the modules are in the same publish unit (bundle). + * However, without some extra information to identify the modules in a bundle, this approach implies that visibility/accessibility cannot be verified after publishing (e.g., while loading). The VM would have to assume that every internal access is good because it has no way to verify it after the publishing time. + * Versioning or upgrades could create problems with this model too, if a version would leave behind some modules that would keep visibility permission but were not intended to. That is something to analyze in more detail and it may or may not be a problem. Essentially the problem is whether verification at publishing time is enough to ensure correctness. It may be argued that the VM knowing the module bundle before and after could be enough to build the dependency graph before and after, and to report errors if any permission inconsistency is detected. + * Alternatively, modules could declare the “bundle” to which they belong. The binary format could have an entry for the set of modules published together, and those would define the scope when checking internal visibility/accessibility. The bundle would still be published together but then the bytecode verifier would have knowledge of which modules to take into account when verifying internal access. + * Friend visibility for selected modules fundamentally provides more fine grained access control than package visibility with bundles of modules. And, since Move does not yet have a concept of multi-module packages, friend visibility is a better option. diff --git a/vendors/move/changes/2-script-visibility.md b/vendors/move/changes/2-script-visibility.md new file mode 100644 index 000000000..afb780fdb --- /dev/null +++ b/vendors/move/changes/2-script-visibility.md @@ -0,0 +1,127 @@ +# Script Visibility + +* Status: Implemented in Move 1.2 + +## Introduction + +Script visibility is a new feature in Move version 1.2 to allow module functions to be safely and directly invoked much like scripts. Previously a function had either public or private visibility, where a public function is accessible anywhere but a private function can be called only from within the module where it is defined. A function with script visibility can be invoked directly, much like scripts, and is restricted to only being callable from scripts or other script visible functions. + +## Motivations + +### Managing the Hash-based Allow-list + +In the Diem Framework, there was a hash-based allowlist of valid scripts that could be sent to the network. If the hash of a script was present in the list, the script could be executed. Otherwise, the transaction was rejected. + +This solution worked but was rather cumbersome, especially if all the hash values change due to something like a new Move bytecode version. In an upgrade scenario, the allowlist would have to be upgraded in the same write-set transaction. While this difficult upgrade path could work, it would not scale well in the future. To the extent possible, Diem should continue to support old transactions, both to ease the upgrade process for clients and also to allow pre-signed transactions that are rarely updated (e.g., for emergency key rotations). The allowlist would then need to include all the old hash values from previous releases, and it would quickly grow in size and become hard to manage. Script visibility solves this problem by including the allowed scripts as part of the Diem Framework instead of tracking their hash values. + +### Diem Framework Updates + +At some time in the future, when Diem allows arbitrary transactions with script-functions, public APIs in the Diem Framework will be extremely difficult to change, but for now, it is still important to evolve the framework with critical changes that are incompatible with scripts from previous versions. This conflicts with the desire to continue supporting transactions from previous releases. With script visibility, the contents of the supported scripts can evolve along with the framework because the Move bytecodes for those scripts are not contained within the transactions, but are instead stored on chain as part of the framework. + +### Meaningless Wrappers + +Many of the scripts we have seen are simple wrappers around a single function call or two. These scripts did not contain any interesting ad-hoc computation (and could not be doing so in the Diem Framework with its allow list). It would be convenient if a module writer could autogenerate scripts for certain functions, or simply mark which functions could be invoked directly, as if they were scripts. + +## Description + +The `script` visibility level solves these problems. In the previous version of Move, functions in a module could be declared as either `public` or private (`Public` or `Private` in the Move bytecode file format). With this change, the possible visibility levels are now: private (no modifier), `public(friend)`, `public(script)`, and `public`. These respectively correspond to `Private`, `Friend`, `Script`, and `Public` in the file format. (See the [Friend Visibility](1-friend-visibility.md) change description for more details on that new feature.) + +A `public(script)` function can only be called from 1) other `public(script)` functions, or 2) from transaction scripts. And, if the function has a signature that meets the necessary restrictions for a script-function, it can be invoked directly by the Move VM as if it was a script. + +### New Visibility Modifier + +`public(script)` is a new visibility modifier that can be applied to any module’s functions. A `public(script)` function can be invoked by any other `public(script)` function (whether or not it is in the same module) or by a script-function. Besides this visibility rule, `public(script)` functions follow the same rules as any other module function, meaning they can invoke private functions, create new struct instances, access global storage (of types declared in that module), etc. + +Unlike script-functions, the signature of `public(script)` functions is not restricted. Any signature that is valid for another module function is a valid signature for a `public(script)` function. But, to be invoked by the Move VM as a script, the `public(script)` function must meet the same restrictions of a script-function. In other words, while every script-function has a restricted signature, the restrictions of a `public(script)` function are checked dynamically when used as an entry point to execution. + +### New VM Entry Point + +A new entry point `execute_script_function` is added to the VM to allow the invocation of a `public(script)` function in published modules. The entry point takes the following signature: + +``` +fn execute_script_function( + &self, + module: &ModuleId, + function_name: &IdentStr, + ty_args: Vec, + args: Vec>, + senders: Vec, + data_store: &mut impl DataStore, + cost_strategy: &mut CostStrategy, + log_context: &impl LogContext, +) -> VMResult<()> +``` + +The entry point is designed to be similar to the existing `execute_script` entry point, with only one change: + +* argument `script: Vec` (i.e., a serialized script in raw bytes) is replaced by a pair of `module: &ModuleId` and `function_name: &IdentStr` that uniquely identifies a `public(script)` function in a published module (assuming the function exists). + +The VM will reject the execution with proper status codes in the following situations: + +* the `module` or `function_name` does not exist +* the function being pointed to is not a `public(script)` function +* the signature of the `public(script)` function does not pass the script signature check: + * All `signer` arguments must occur before non-`signer` arguments + * The function does not return any value + * Each non-`signer` type in function type arguments is a valid type for a constant + * Ostensibly, the type has the `copy` ability and is not a struct + * Each type in the function type variables is closed, i.e., does not refer to other type variables +* the `senders`, `args`, or `ty_args` do not match the declared function signature. + +## Examples + +The feature is best used when you have a script that is a simple wrapper around a function in a module: + +``` +script { + fun call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) + } +} +``` + +Changing the module’s function from `public` to `public(script)` will remove the need for this simple wrapper script: + +``` +address 0x42 { +module M { + ... + // Replace previous "public" visibility... + public(script) fun foo(account: signer, amount: u64) { + ... + } +} +} +``` + +However, keep in mind that the function can now only be called from other `public(script)` functions or script-functions. + +``` +address 0x43 { +module Other { + fun private_call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) // ERROR Now invalid + } + + public fun public_call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) // ERROR Now invalid + } + + public(script) fun script_call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) // Still a valid call + } +} +} + +script { + fun still_valid(account: signer) { + 0x42::M::foo(account, 0) // Still a valid call + } +} +``` + +## Alternatives + +We did not see many other options that would address the script versioning problem caused by the hash-based allowlist. Converting transaction scripts into `public(script)` functions that are published and change alongside the corresponding module was the most straightforward solution. + +For the issue of meaningless wrappers alone, we considered compiler support to have scripts auto-generated. The generation by the compiler would be relatively simple, but it is unnecessary in the presence of `public(script)` functions. diff --git a/vendors/move/changes/3-abilities.md b/vendors/move/changes/3-abilities.md new file mode 100644 index 000000000..ce1f08efc --- /dev/null +++ b/vendors/move/changes/3-abilities.md @@ -0,0 +1,439 @@ +# Abilities + +* Status: Implemented in Move 1.2 + +## Introduction + +Abilities are a new feature in Move version 1.2 to give more control over what actions are permissible for values of a given type. Previously in Move’s type system, there were copyable values and `resource` values. In this old system, copyable values were unrestricted, but resource values could not be copied and had to be used. With abilities, Move’s type system grants more fine grained control, allowing types to specifically allow certain operations for their values that were previously implicitly allowed/denied depending on the “kind” (copyable or resource). + +## Motivations + +Move’s kind system (copyable vs. resource structs) has been great, but it is not expressive enough for certain applications. Resource types are very powerful, but the system bundles up a lot of behavior into one kind, which does not always meet application needs. In the Diem Framework, there has been a need for a “hot potato” type for capabilities—that is some type that cannot be copied or dropped (like a resource), but cannot be stored in global storage. It is then a “hot potato” since you must keep passing it around and it must be consumed before the transaction completes. A type with these restrictions would allow the Move prover to verify the usage of these specific capabilities. + +Extending the kind system just to handle this “hot potato” example is likely not the best future-proof solution. A more granular system can give programmers more control to implement not only “hot potato” types but also serve yet unknown needs. As such, we want the new system to be flexible enough to be extended in the future without requiring another large refactoring of the type system. + +## Description + +The kinds copyable and resource are replaced by four new *abilities*. These abilities gate access to various bytecode instructions. In order for a value to be used with the bytecode instruction, it must have the ability required (if one is required at all—not every instruction is gated by an ability). + +### The Abilities + +The four added abilities are `copy`, `drop`, `store`, and `key`. Broken down in detail: + +* `copy` + * Allows values of types with this ability to be copied + * Gates: `CopyLoc` and `ReadRef` + * If a value has `copy`, all values reachable inside of that value have `copy`. +* `drop` + * Allows values of types with this ability to be popped/dropped. + * Ownership does not *have* to be transferred + * Gates: `Pop`, `WriteRef`, `StLoc`, `Eq` and `Neq` + * Values left in local variables must have `drop` when the function returns with `Ret` + * If a value has `drop`, all values reachable inside of that value have `drop`. +* `store` + * Allows values of types with this ability to exist inside a struct in global storage + * But not necessarily as a top-level value in global storage + * This is the only ability currently that is not directly checked by an operation. But it is indirectly checked when `key` is checked + * If a value has `store`, all values reachable inside of that value have `store`. +* `key` + * Allows the type to serve as a key for global storage operations + * Letting values of types with this ability exist at the top-level of global storage + * Gates: `MoveTo`, `MoveFrom`, `BorrowGlobal`, `BorrowGlobalMut`, and `Exists` + * If a value has `key`, all values reachable inside of that value have `store`. + +### Primitive Types + +Most primitive types all have `copy`, `drop`, and `store` with the exception of `signer`. + +* `bool`, `u8`, `u64`, `u128`, and `address` all have `copy`, `drop`, and `store`. +* `signer` has `drop` + * Cannot be copied and cannot be put into global storage +* `vector` may have `copy`, `drop`, and `store` depending on the abilities of `T`. + * See [Conditional Abilities with Generic Types](#Conditional-Abilities-with-Generic-Types) for more details. +* Immutable references `&` and mutable references `&mut` both have `copy` and `drop`. + * This refers to copying and dropping the reference itself, not what they refer to. + * References cannot appear in global storage, hence they do not have `store`. + +### Annotating Structs + +To declare that a `struct` has an ability, it is declared with `has ` after the struct name but before the fields. For example: + +``` +struct Ignorable has drop { f: u64 } +struct Pair has copy, drop, store { x: u64, y: u64 } +``` + +In this case `Ignorable` has the `drop` ability, and `Pair` has `copy`, `drop`, and `store`. + +When declaring a struct’s abilities, certain requirements are placed on the fields. All fields must satisfy these constraints. These rules are necessary so that structs satisfy the reachability rules for abilities given above. If a struct is declared with the ability... + +* `copy`, all fields must have `copy` +* `drop`, all fields must have `drop` +* `store`, all fields must have `store` +* `key`, all fields must have `store` + * `key` is the only ability currently that doesn’t require itself. + +For example: + +``` +// A struct without any abilities +struct NoAbilities {} + +struct WantsCopy has copy { + f: NoAbilities, // ERROR 'NoAbilities' does not have 'copy' +} +``` + +and similarly: + +``` +// A struct without any abilities +struct NoAbilities {} + +struct MyResource has key { + f: NoAbilities, // Error 'NoAbilities' does not have 'store' +} +``` + +### Basic Examples + +**Copy** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } + +fun example(x: u64, s: S) { + let x2 = copy x; // Valid, 'u64' has 'copy' + let s2 = copy s; // Valid, 'S' has 'copy' +} + +fun invalid(account: signer, n: NoAbilities) { + let a2 = copy account; // Invalid, 'signer' does not have 'copy' + let n2 = copy n; // Invalid, 'NoAbilities' does not have 'drop' +} +``` + +**Drop** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } + +fun unused() { + true; // Valid, 'bool' has 'drop' + S { f: false }; // Valid, 'S' has 'drop' +} + +fun left_in_local(account: signer): u64 { + let b = true; + let s = S { f: false }; + // Valid return: 'account', 'b', and 's' have values + // but 'signer', 'bool', and 'S' have 'drop' + 0 +} + +fun invalid_unused() { + NoAbilities {}; // Invalid, Cannot ignore 'NoAbilities' without 'drop' +} + +fun invalid_left_in_local(): u64 { + let n = NoAbilities{}; + // Invalid return: 'n' has a value and 'NoAbilities' does not have 'drop' + 0 + +} +``` + +**Store** + +``` +// 'MyInnerResource' is declared with 'store' so all fields need 'store' +struct MyInnerResource has store { + yes: u64, // Valid, 'u64' has 'store' + // no: signer, Invalid, 'signer' does not have 'store' +} + +// 'MyResource' is declared with 'key' so all fields need 'store' +struct MyResource has key { + yes: u64, // Valid, 'u64' has 'store' + inner: MyInnerResource, // Valid, 'MyInnerResource' has 'store' + // no: signer, Invalid, 'signer' does not have 'store' +} +``` + +**Key** + +``` +struct NoAbilities {} +struct MyResource has key { f: u64 } + +fun valid(account: &signer) acquires MyResource { + let addr = signer::address_of(account); + let has_resource = exists(addr); // Valid, 'MyResource' has 'key' + if (!has_resource) { + move_to(account, MyResource { f: 0 }) // Valid, 'MyResource' has 'key' + }; + let r = borrow_global_mut(addr) // Valid, 'MyResource' has 'key' + r.f = r.f + 1; +} + +fun invalid(account: &signer) { + let has_it = exists(addr); // Invalid, 'NoAbilities' does not have 'key' + let NoAbilities {} = move_from(addr); // Invalid, does not have 'key' + move_to(account, NoAbilities {}); // Invalid, 'NoAbilities' does not have 'key' + borrow_global(addr); // Invalid, 'NoAbilities' does not have 'key' +} +``` + +### Constraining Generics + +Abilities can used to constrain generics, meaning that only types with that ability can instantiate that type parameter. This can be used on both function and struct type parameters: + +``` +fun foo(x: T): (T, T) { (copy x, x) } +struct CopyCup has copy { item: T } +``` + +Type parameters can have more than one constraint, signified with `+` + +``` +fun bar(x: T): T { copy x } +struct AllCup has copy, drop, store, key { item: T } +``` + +### Conditional Abilities with Generic Types + +When abilities are annotated on a generic type, not all instances of that type are guaranteed to have that ability. Consider this struct declaration: + +``` +struct Cup has copy, drop, store, key { item: T } +``` + +The type parameter `T` is assumed to be used inside of the struct, so the abilities are only granted if the type parameters meet the requirements described above for fields. That means: + +* `Cup` has the ability `copy` only if `T` has `copy`. +* It has `drop` only if `T` has `drop`. +* It has `store` only if `T` has `store`. +* It has `key` only if `T` has `store`. + +This behavior might be a bit confusing at first, but it is extremely useful for collection-like types. Consider `vector`: we could consider it to have the following type declaration: + +``` +vector has copy, drop, store; +``` + +With this, you can copy a `vector` value only if the inner elements can be copied. You can ignore a `vector` value only if the inner elements can be ignored/dropped. And, a `vector` can be in global storage only if the inner elements can be in global storage. + +### More Examples + +**Conditional Copy** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun example(c_x: Cup, c_s: Cup) { + // Valid, 'Cup' has 'copy' because 'u64' has 'copy' + let c_x2 = copy c_x; + // Valid, 'Cup' has 'drop' because 'S' has 'drop' + let c_s2 = copy c_s; +} + +fun invalid(c_account: Cup, c_n: Cup) { + // Invalid, 'Cup' does not have 'copy'. + // Even though 'Cup' was declared with copy, the instance does not have 'copy' + // because 'signer' does not have 'copy' + let c_account2 = copy c_account; + // Invalid, 'Cup' does not have 'drop' + // because 'NoAbilities' does not have 'drop' + let c_n2 = copy c_n; +} +``` + +**Drop** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun unused() { + Cup { item: true }; // Valid, 'Cup' has 'drop' + Cup { item: S { f: false }}; // Valid, 'Cup' has 'drop' +} + +fun left_in_local(c_account: Cup): u64 { + let c_b = Cup { item: true }; + let c_s = Cup { item: S { f: false }}; + // Valid return: 'c_account', 'c_b', and 'c_s' have values + // but 'Cup', 'Cup', and 'Cup' have 'drop' + 0 +} + +fun invalid_unused() { + // Invalid, Cannot ignore 'Cup' because it does not have 'drop'. + // Even though 'Cup' was declared with 'drop', the instance does not have 'drop' + // because 'NoAbilities' does not have 'drop' + Cup { item: NoAbilities {}}; +} + +fun invalid_left_in_local(): u64 { + let n = Cup { item: NoAbilities {}}; + // Invalid return: 'c_n' has a value + // and 'Cup' does not have 'drop' + 0 + +} +``` + +**Store** + +``` +struct Cup has copy, drop, store { item: T } + +// 'MyInnerResource' is declared with 'store' so all fields need 'store' +struct MyInnerResource has store { + yes: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} + +// 'MyResource' is declared with 'key' so all fields need 'store' +struct MyResource has key { + yes: Cup, // Valid, 'Cup' has 'store' + inner: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} +``` + +**Key** + +``` +struct NoAbilities {} +struct MyResource has key { f: T } + +fun valid(account: &signer) acquires MyResource { + let addr = signer::address_of(account); + // Valid, 'MyResource' has 'key' + let has_resource = exists>(addr); + if (!has_resource) { + // Valid, 'MyResource' has 'key' + move_to(account, MyResource { f: 0 }) + }; + // Valid, 'MyResource' has 'key' + let r = borrow_global_mut>(addr) + r.f = r.f + 1; +} + +fun invalid(account: &signer) { + // Invalid, 'MyResource' does not have 'key' + let has_it = exists>(addr); + // Invalid, 'MyResource' does not have 'key' + let NoAbilities {} = move_from(addr); + // Invalid, 'MyResource' does not have 'key' + move_to(account, NoAbilities {}); + // Invalid, 'MyResource' does not have 'key' + borrow_global(addr); +} +``` + +### Backwards Compatibility + +The new ability system is backwards compatible with the kind system in nearly all cases. At the bytecode level, old modules and scripts with kinds can be loaded as if they were written with abilities. + +For any struct: + +* If it was declared as a “copyable”, non-`resource` struct, the struct will be given the abilities `copy`, `drop`, and `store`. +* If it was declared as a `resource`, the struct will be given the abilities `store` and `key`. +* For type parameters: + * `copyable` becomes `copy + drop` + * `resource` becomes `key` + * `store` is not given as it is not needed in the constraint position. Any usage will still work. + +For any function: + +* For type parameters: + * `copyable` becomes `copy + drop + store` + * `resource` becomes `key + drop` + * `store` is needed as it is not simple to determine if the type parameter will be used with global storage operations. + +Putting these rules together, the old code + +``` +struct S {} +resource struct R {} + +fun foo() {} +``` + +will be loaded as if it was written as: + +``` +struct S has copy, drop, store {} +struct R {} + +fun foo() {} +``` + +This leads to one spot where there is a breaking change, namely any function instantiated with `signer` as a type parameter will not now load because the type parameter will have the `store` constraint—all old function type parameters are given the `store` constraint—but `signer` does not have `store`. Given the restricted usage of `signer`, this is likely an extreme edge case, and we do not foresee it being an issue in practice for any project. + +## Alternatives + +### Extending the Kind System + +For the main motivating example for this change, it was considered to add a “hot potato” kind to the system. +In the kind system there was: + +* `Copyable` which corresponds to `copy + drop + store`, +* `Resource` which corresponds to `key + store` +* `All` which sometimes corresponds to `store` and sometimes to no-ability + +Often this was viewed with a sub-kinding system where `Copyable <: All` and `Resource <: All`. Adding a `HotPotato` kind to this system would be bit tricky, possibly giving a hierarchy of `Copyable <: All` and `Resource <: HotPotato <: All`. But, this could become a mess if: + +* There needed to be an `AllWithStore` kind, giving `Copyable <: AllWithStore <: All` and `Resource <: AllWithStore <: All` and `Resource <: HotPotato <: All`. +* If any other kind was added, the complexity could quickly explode. + +The complexity around this sub-kinding approach led to the more granular approach described above with abilities. We were particularly worried about needing another kind in a year or two and having the whole thing collapse. With abilities, we can easily add new ones over time if needed. + +### Explicit Conditional Abilities + +The current rules around generics being conditional for generic types might be potentially confusing, especially given the keyword `has`. For instance: + +``` +struct Cup has copy, drop, store { item: T } +``` + +Despite effectively saying “has copy” and “has drop” and “has store”, `Cup` may or may not have the ability depending on what `T` is. This might be rather confusing. It was considered then that for generic types you would write: + +``` +struct Cup has ?copy, ?drop, ?store { item: T } +``` + +This would mean exactly what it means today, where it may or may not have the ability depending on `T` and then using `has` without the question mark `?` + +``` +struct Ex has copy {} +``` + +would be equivalent to: + +``` +struct Ex has ?copy {} +``` + +The potential problem then comes in that there are a lot of combinations that are meaningless. So, in many cases the compiler would yell at you that there is really just one valid choice. + +* `struct Ex has copy` is sort of redundant and could just be `struct Ex has copy`. +* For a non-generic type, `struct Ex has ?copy` is meaningless in some way, as every instance has the ability, and it is the same as `struct Ex has copy`. + +In short, having the option to have the question mark `?` caused there to be more cases and possibly more confusion. Furthermore this system was not more expressive, as a programmer could always annotate the generic `struct Cup has copy`, this would force every instance to have `copy` in a more explicit manner. In short, just having one option and one rule that might be a bit more confusing in the way it reads at first, but reduces the amount of complexity to consider when declaring a new struct. + +### Alternative Names + +Many different names were considered for all aspects of the abilities system. + +* For the name “ability” itself, “kinds”, “traits”, “type classes”, and “interfaces” were all considered. But these items used in other programming languages are usually used to describe programmer-defined items. There is no way for programmers to define their own abilities. Additionally, abilities do not give anything that looks like dynamic dispatch. So, while those other names might be more familiar, we worried they would be too misleading. +* `copyable` and `dropable` and `storable` were all considered, but they felt too wordy. Shorter names felt more appropriate. +* `mustuse` or `mustmove` were considered for `drop`, but again, the more concise name felt better even if the others were more informative. +* `resource` was considered instead of `key`. The `key` ability is very similar to the `resource` keyword in many cases, but it felt very weird that something like a `Coin` which might have been `resource struct Coin` in the old system, would not be `struct Coin has store` and would not be a “resource”. Thus we are saving the word “resource” to be used in documentation for any time that does not have `copy` or `drop`. diff --git a/vendors/move/changes/4-unit-testing.md b/vendors/move/changes/4-unit-testing.md new file mode 100644 index 000000000..464d1ce30 --- /dev/null +++ b/vendors/move/changes/4-unit-testing.md @@ -0,0 +1,345 @@ +# Unit Testing + +* Status: Implemented in Move 1.3 + +## Introduction + +Unit testing is a new feature in Move version 1.3 to allow Move programmers to more easily and concisely test individual functions and features. Previously, the only way to test Move code was using more heavyweight expected-value and transaction-based tests via the Move CLI and Diem functional test framework. Additionally, it was hard — if not impossible — to set up arbitrary state for testing, to test non-public functions, and to have test-only dependencies, functions, and datatypes. With the new Move unit testing feature these are all possible and easy to express. + +## Motivation + +Being able to test code thoroughly is an essential ability when developing Move code. However, without a unit testing framework for Move, achieving high test coverage for both public and private functions that is clear and easily maintainable is a challenging task. + +Move unit tests are written in the module whose functionality they are testing. Because of this, unit tests have access to private functions and can freely construct and publish instances of datatypes defined in the module. This allows a more declarative and transparent style of testing as compared to previous options, where complex sequences of transactions could be needed to set up the state in a specific manner to test a particular code path in a function. + +Sometimes there are cross-module data dependencies, functions, or datatypes that you would like to have for testing purposes only. Move unit tests allow expressing that modules, and module members (`use`s, functions, and datatypes) are for testing purposes only. When members are annotated as `#[test_only]` or `#[test]` they will not appear in the compiled bytecode outside of testing. For those familiar with Rust, this is similar to `#[cfg(test)]` and `#[test]` respectively. + +## Description + +Unit testing for Move adds three new annotations to the Move source language: + +* `#[test]` +* `#[test_only]`, and +* `#[expected_failure]`. + +They respectively mark a function as a test, mark a module or module member (`use`, function, or struct) as code to be included for testing only, and mark that a test is expected to fail (abort). These annotations can be placed on a function with any visibility. Whenever any module or module member is annotated as `#[test_only]` or `#[test]`, it will not be included in the compiled bytecode unless it is compiled for testing. + + +### Testing Annotations: Their Meaning and Usage + +Both the `#[test]` and `#[expected_failure]` annotations can be used either with or without arguments. + +Without arguments, the `#[test]` annotation can only be placed on a function with no parameters. This annotation simply marks this function as a test to be run by the unit testing harness. + +``` +#[test] // OK +fun this_is_a_test() { ... } + +#[test] // Will fail to compile since the test takes an argument +fun this_is_not_correct(arg: signer) { ... } +``` + +A test can also be annotated as an `#[expected_failure]`. This annotation marks that the annotated test should abort — however the exact abort code is not checked. The test will be marked as failing only if the test fails with a non-abort error, or does not abort. Only functions that have the `#[test]` annotation can also be annotated as an #`[expected_failure]`. + +``` +#[test] +#[expected_failure] +public fun this_test_should_abort_and_pass() { abort 1 } + +#[test, expected_failure] // Can have multiple in one attribute. This test will pass. +public(script) fun this_other_test_should_abort_and_pass() { abort 1 } +``` + +With arguments, a test annotation takes the form `#[test( =
, ..., =
)]`. If a function is annotated in such a manner, the function's parameters must be a permutation of the parameters <`param_name_1>, ..., `, i.e., the order of these parameters as they occur in the function and their order in the test annotation do not have to be the same, but they must be able to be matched up with each other by name. + +Only parameters with a type of `signer` are supported as test parameters. If a non-`signer` parameter is supplied, the test will result in an error when run. + +``` +#[test(arg = @0xC0FFEE)] // OK +fun this_is_correct_now(arg: signer) { ... } + +#[test(wrong_arg_name = @0xC0FFEE)] // Not correct: arg name doesn't match +fun this_is_incorrect(arg: signer) { ... } + +#[test(a = @0xC0FFEE, b = @0xCAFE)] // OK. We support multiple signer arguments, but you must always provide a value for that argument +fun this_works(a: signer, b: signer) { ... } + +// somewhere a named address is declared +#[test_only] // test-only named addresses are supported +address TEST_NAMED_ADDR = @0x1; +... +#[test(arg = @TEST_NAMED_ADDR)] // Named addresses are supported! +fun this_is_correct_now(arg: signer) { ... } +``` + +An expected failure annotation can also take the form `#[expected_failure(abort_code = )]`. If a test function is annotated in such a way, the test must abort with an abort code equal to ``. Any other failure or abort code will result in a test failure. + +``` +#[test, expected_failure(abort_code = 1)] // This test will fail +fun this_test_should_abort_and_fail() { abort 0 } + +#[test] +#[expected_failure(abort_code = 0)] // This test will pass +fun this_test_should_abort_and_pass_too() { abort 0 } +``` + +A module and any of its members can be declared as test only. In such a case the item will only be included in the compiled Move bytecode when compiled in test mode. Additionally, when compiled outside of test mode, any non-test `use`s of a `#[test_only]` module will raise an error during compilation. + +``` +#[test_only] // test only attributes can be attached to modules +module ABC { ... } + +#[test_only] // test only attributes can be attached to named addresses +address ADDR = @0x1; + +#[test_only] // .. to uses +use 0x1::SomeOtherModule; + +#[test_only] // .. to structs +struct SomeStruct { ... } + +#[test_only] // .. and functions. Can only be called from test code, but not a test +fun test_only_function(...) { ... } +``` + +### Running Unit Tests + +Unit tests can be compiled and run by the `move-unit-test` crate. It is designed to work out-of-the box, so all you need to start running tests is to pass the files—or directories containing files—that you wish to test (and all dependencies): + +``` +$ cargo run --bin move-unit-test ... +``` + +When running tests, every test will either `PASS`, `FAIL`, or `TIMEOUT`. If a test case fails, the location of the failure along with the function name that caused the failure will be reported if possible. You can see an example of this below. + +A test will be marked as timing out if it exceeds the maximum gas that can be executed for any single test. When a gas table is not provided, each bytecode instruction is assigned a gas cost of 1 unit. This bound can be changed using the options below, and its default value is set to 5000 gas units. Additionally, while the result of a test is always deterministic, tests are run in parallel by default, so the ordering of test results in a test run is non-deterministic unless running with only one thread (see `OPTIONS` below). + +There are also a number of options that can be passed to the unit testing binary to fine-tune testing, and to help debug failing tests. These are: + +``` +FLAGS: + --stackless Use the stackless bytecode interpreter to run the tests and cross check its results with the + execution result from Move VM + -g, --state_on_error Show the storage state at the end of execution of a failing test + -h, --help Prints help information + -l, --list List all tests + -s, --statistics Report test statistics at the end of testing + -V, --version Prints version information + -v, --verbose Verbose mode + +OPTIONS: + -f, --filter A filter string to determine which unit tests to run + -i, --gas_limit Bound the amount of gas used by any one test. [default: 1_000_000] + -t, --threads Number of threads to use for running tests [default: 8] + +ARGS: + ... Source files +``` + +While each of these flags and options are fairly self-explanatory, it is worth mentioning that when filtering tests with the `-f` option, any test whose fully qualified name (i.e., `address::module::function_name`) contains the `` string will be run. + +### Compilation + +You should always use the unit testing framework for unit testing Move code. However, there may be times when you may wish to include test-only code outside of unit testing. In such scenarios Move source code can be compiled with test-code included by passing the `--test` flag to the Move compiler. + +## Examples + +A simple module using some of the unit testing features is shown in the following example: + +``` +// filename: MyModule.move +module 0x1::MyModule { + + struct MyCoin has key { value: u64 } + + public fun make_sure_non_zero_coin(coin: MyCoin): MyCoin { + assert(coin.value > 0, 0); + coin + } + + public fun has_coin(addr: address): bool { + exists(addr) + } + + #[test] + fun make_sure_non_zero_coin_passes() { + let coin = MyCoin { value: 1 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test] + // Or #[expected_failure] if we don't care about the abort code + #[expected_failure(abort_code = 0)] + fun make_sure_zero_coin_fails() { + let coin = MyCoin { value: 0 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test_only] // test only helper function + fun publish_coin(account: &signer) { + move_to(account, MyCoin { value: 1 }) + } + + #[test(a = @0x1, b = @0x2)] + fun test_has_coin(a: signer, b: signer) { + publish_coin(&a); + publish_coin(&b); + assert(has_coin(@0x1), 0); + assert(has_coin(@0x2), 1); + assert(!has_coin(@0x3), 1); + } +} +``` + +### Running Tests + +``` +$ cargo run --bin move-unit-test MyModule.move +Running Move unit tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +[ PASS ] 0x1::MyModule::test_has_coin +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +### Using Test Flags + +#### `-f ` or `--filter ` +This will only run tests whose fully qualified name contains ``. For example if we wanted to only run tests with `"zero_coin"` in their name: + +``` +$ cargo run --bin move-unit-test MyModule.move -f zero_coin +Running Move unit tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +Test result: OK. Total tests: 2; passed: 2; failed: 0 +``` + +#### `-i ` or `--gas_limit ` +This bounds the amount of gas that can be consumed for any one test to ``: + +``` +cargo run --bin move-unit-test -i 0 MyModule.move +Running Move unit tests +[ TIMEOUT ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ TIMEOUT ] 0x1::MyModule::make_sure_zero_coin_fails +[ TIMEOUT ] 0x1::MyModule::test_has_coin + +Test failures: + +Failures in 0x1::MyModule: + +┌── make_sure_non_zero_coin_passes ────── +│ Test timed out +└────────────────── + + +┌── make_sure_zero_coin_fails ────── +│ Test timed out +└────────────────── + + +┌── test_has_coin ────── +│ Test timed out +└────────────────── + +Test result: FAILED. Total tests: 3; passed: 0; failed: 3 +``` + +#### `-s` or `--statistics` +With these flags you can gather statistics about the tests run and report the runtime and gas used for each test. For example, if we wanted to see the statistics for the tests in the `MyModule` example above: + +``` +$ cargo run --bin move-unit-test MyModule.move -s +Running tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +[ PASS ] 0x1::MyModule::test_has_coin + +Test Statistics: + +┌───────────────────────────────────────────────┬────────────┬───────────────────────────┐ +│ Test Name │ Time │ Gas Used │ +├───────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::MyModule::make_sure_non_zero_coin_passes │ 0.005 │ 1 │ +├───────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::MyModule::make_sure_zero_coin_fails │ 0.003 │ 1 │ +├───────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::MyModule::test_has_coin │ 0.004 │ 1 │ +└───────────────────────────────────────────────┴────────────┴───────────────────────────┘ + +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +#### `-g` or `--state-on-error` +These flags will print the global state for any test failures. e.g., if we added the following (failing) test to the `MyModule` example: + +``` +module 0x1::MyModule { + ... + #[test(a = @0x1)] + fun test_has_coin_bad(a: signer) { + publish_coin(&a); + assert(has_coin(@0x1), 0); + assert(has_coin(@0x2), 1); + } +} +``` + +we would get get the following output: + +``` +$ cargo run --bin move-unit-test MyModule.move -g +Running tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +[ PASS ] 0x1::MyModule::test_has_coin +[ FAIL ] 0x1::MyModule::test_has_coin_bad + +Test failures: + +Failures in 0x1::MyModule: + +┌── test_has_coin_bad ────── +│ error: +│ +│ ┌── MyModule.move:46:9 ─── +│ │ +│ 46 │ assert(has_coin(@0x2), 1); +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to abort but it aborted with 1 here +│ · +│ 43 │ fun test_has_coin_bad(a: signer) { +│ │ ----------------- In this function in 0x1::MyModule +│ │ +│ +│ +│ ────── Storage state at point of failure ────── +│ 0x1: +│ => key 0x1::MyModule::MyCoin { +│ value: 1 +│ } +│ +└────────────────── + +Test result: FAILED. Total tests: 4; passed: 3; failed: 1 +``` + +## Ongoing Work + +Support for test-only native functions is currently being added to the unit testing framework. With this addition comes a new way of creating an arbitrary number of `signer` values in test-only code. We expect these features to be available in release 1.4. + +We also plan to support running Move unit tests from the Move CLI and expect that this to be supported in release 1.4. + +## Alternatives + +In the development of unit tests, there were a couple of alternatives considered, some of which you as a Move programmer have at your disposal already, so we highlight the differences here. + +### Expected Value Tests + +Move already supports [expected value tests](https://github.com/move-language/move/tree/main/language/tools/move-cli#testing-with-the-move-cli) in the Move CLI, however these cover a different aspect of testing for Move. In particular, there is no concept of test-only code and test-only dependencies, which makes testing non-public functions much more difficult. Additionally, each expected value test entry must be a transaction or script function. Because of this, the expected value tests rely on a specific Move adapter implementation, whereas the unit tests do not rely on an adapter implementation and rely solely on the Move compiler and VM. + +Due to the design of unit tests, unit tests make it easier to test the individual units of code that comprise a Move module. However, because the unit tests do not require or use an adapter, they do not support certain features that you may wish to test. E.g., there is no way in Move unit tests to query if a specific event has been emitted. + +### Test Modules + +The unit tests for Move are function and annotation based: each test and test-only members are declared by attaching an annotation to them. During development we also considered a module-based approach where a separate test module could be declared that contained the tests for a module (and that the compiler would inline so the tests could access private functions and construct datatypes declared in the module). We decided against supporting such an option at this time for simplicity, and to make the additional syntax and the semantics as close as possible to what currently exists in Move, but that option could still be added in the future. diff --git a/vendors/move/changes/5-named-addresses.md b/vendors/move/changes/5-named-addresses.md new file mode 100644 index 000000000..936db6803 --- /dev/null +++ b/vendors/move/changes/5-named-addresses.md @@ -0,0 +1,200 @@ +# Named Addresses + +- Status: Implemented in Move 1.4, updated in Move 1.5 + +## Introduction + +Named addresses are a new source language only feature. (That is, the named address feature is +compiled away and not present in the Move bytecode format). The feature allows names to be used in +place of numerical values in any spot where addresses are used. Named addresses are declared as top +level elements (outside of modules and scripts) in Move Packages, or passed as +arguments to the Move compiler. + +With the landing of this feature, Move standard library modules now reside under the address `Std`, +e.g. `std::vector`. Similarly, Diem Framework modules now reside under the address `DiemFramework`, +e.g. `DiemFramework::XUS`. + +Named address declarations are opaque, meaning they must be accessed via the name and not their +underlying numeric value. Any existing code must be updated to use named addresses when accessing +standard library or Diem Framework modules. + +Alongside this change, there is new syntax for address literals when used as expression values, e.g. +`let addr = @0x42;`. + +## Motivations + +Fixed, numerical addresses were "good enough" for the language starting off, but the inability to +set addresses via a configuration at build time severely hinders code portability and usability. +Additionally, the lack of named address support has been painful both for account configuration in +testing and for basic readability of code. + +To combat this, we are adding named addresses. They compile down to the same address system that +exists today, but it greatly increases the portability, testability, and readability of source +language programs. + +## Description + +### New Address Literal Syntax + +Addresses now come in two flavors, named or numerical. The syntax for a named address follows the +same rules for any named identifier in Move. The syntax of a numerical address is no longer +restricted to `0x`-prefixed values, and now any valid numerical literal can be used. + +To make room for the named address feature, address expression values have a new syntax. This new +syntax reduces the complexity around named addresses as it prevents shadowing issues around module +members (specifically constants) and local variables. + +In the old syntax, all address values began with `0x` and this hex prefix could not be used for +integer values. In the new syntax, all address values are prefixed with `@`. Following the `@` +operator any valid address can be used. For example: + +```move +let _: u8 = 0x1u8; +let _: u64 = 0x42u64; +let _: u128 = 0x42u128; +let a1: address = @std; +let a2: address = @66; +let a3: address = @0x42; +``` + +You can think of `@` as an operator that takes an address from being a namespace item to an +expression item. + +Named addresses are not declared in Move source code. Instead they +must be declared---and given a value---when invoking the Move compiler. E.g., + +```bash +cargo run --bin move-build --addresses MyAddr=0x42 ... +``` + +A named address can be used in both module accesses and as expression values (with the new +`@` syntax) + +```move +script { + fun example() { + MyAddr::M::foo(@MyAddr); + } +} +``` + +A named address can be used multiple times throughout a program. + +```move +// file1.move +module MyAddr::M { + ... +} +``` + +```move +// file2.move +address MyAddr { +module N { + ... +} +} +``` + +### Assigning Named Addresses + +Named addresses can only be assigned a value by passing their value as a parameter to the compiler with `=`: + +```bash +cargo run --bin move-build --addresses MyAddr=0xC0FFEE ... +``` + +An address can be assigned any number of times on the command line as long as it is given only _one_ value. +The following would be fine, since the address `MyAddr` is given the same value in both assignments: + +```bash +cargo run --bin move-build --addresses MyAddr=0xC0FFEE MyAddr=12648430 ... # decimal representation of 0xC0FFEE +``` + +Assigning `MyAddr` two different values will result in an error: + +```bash +cargo run --bin move-build --addresses MyAddr=0xC0FFEE MyAddr=0xDEADBEEF... # ERROR! +``` + +### Opaqueness + +Address assignments, and the name system as whole, only exist at the source +language level and during compilation. Names will be fully substituted for +their value at the byte code level. So the example from before would be +equivalent to + +```move +script { + fun example() { + 0xC0FFEE::M::foo(@0xC0FFEE); + } +} +``` + +But at the source language level, the two are not interchangeable. If we had the declaration: + +```move +module MyAddr::M { + public fun bar() {} +} +``` + +The function `M::bar` _must_ be accessed through the `MyAddr` named address, not through the +numerical value assigned to it. + +For example: + +```move +script { + fun example() { + // ERROR! 0xC0FFEE::M::bar(); + MyAddr::M::bar() + } +} +``` + +## Move Standard Library and Diem Framework Modules + +As mentioned above, all standard library modules now live in `Std` and all Diem Framework modules +live in `DiemFramework`. The `DiemFramework` address is set to `0x1` and this hard-coded assignment +will be fine. However, our hope is to allow `Std` to be assigned different numerical values +depending on the deployment of those modules. For now, `Std` has a hardcoded assignment of `0x1`. +See the 'Future Work' section below for details about how this might work in the future. + +## Backwards Compatibility + +Since, all standard library modules and all Diem Framework modules live in `Std` and `DiemFramework` +respectively, source code must be updated to use those named addresses. The named addresses are +opaque, so the numeric values can no longer be used to access the modules. For example, any use of +`0x1::Vector` must now be `std::vector`. + +Note, as this is just a syntactic change, the compiled module binaries will not be affected. + +## Update for release 1.5 + +The support for assigning values to named addresses in Move source code and declaring named addresses in release 1.4 + +```move +address MyAddr = 0x19; +``` + +and + +```move +address MyAddr; +``` + +was removed. + +Support for assigning address values was added to the command line and compiler +options were added for use in Move packages and the Move command line as described above. + + +## Future Work + +Named address support will be expanded in a new package system. The intent is that with this system, +a Move program will never assign a value to a named address within the `*.move` files. Instead, all +assignment of a named addresses will exist in a config file, similar to Rust's `Cargo.toml` files. +To enable this package system, additional support will likely be needed from the compiler for +configuring and assigning named addreses. diff --git a/vendors/move/changes/6-phantom-type-params.md b/vendors/move/changes/6-phantom-type-params.md new file mode 100644 index 000000000..81c454e2a --- /dev/null +++ b/vendors/move/changes/6-phantom-type-params.md @@ -0,0 +1,112 @@ +# Phantom Type Parameters + +- Status: Implemented in Move 1.4 + +## Introduction + +A _phantom type parameter_ is one that doesn't show up at runtime, but is checked statically at +compile time. Phantom type parameters can be useful in a couple of situations. For example, the +struct `Event::EventHandle` in the Move Standard library doesn't contain any field of type `T`, +but uses the type parameter to ensure at the type level that the handle can only be used for +messages of type `T`. Another prominent example is `Diem::Diem`, which is generic on a +`CoinType` specifying the currency of the coin and allowing code to be written generically on any +currency. As a last example, the capabilities in `Vault` also rely heavily on phantom type +parameters. + +Previously, Move's type system didn't make a difference on whether a type parameter was phantom, but +with this new feature, a struct's type parameter can be explicitly declared as phantom. A parameter +declared as phantom is not considered when computing the +[conditional abilities with generic types](3-abilities.md#Conditional-Abilities-with-Generic-Types). +For this relaxed rule to be sound, Move's type system guarantees that a parameter declared as +phantom is either not used at all in the struct definition, or it is only used as an argument to +type parameters also declared as phantom. + +## Motivations + +Previously, defining a struct `S` with a phantom type parameter required spurious ability +annotations to satisfy the requirements of the abilities declared for `S`. This resulted in +increased chance of bugs and security vulnerability because types had to be weakened with +unnecessary ability declarations. Moreover, the spurious annotations were infectious, requiring many +functions generic on the phantom type parameter to also include the necessary constraints. With the +new feature, arguments to phantom type parameters are not considered when deriving the abilities for +generic types, thus avoiding the need for spurious ability annotations. + +For example, `Diem::Diem` is declared with the ability `key`. This required all arguments +to `CoinType` to be declared with `store`. Specifically, the types `XUS::XUS` and `XDX::XDX` were +forced to have a `store` annotation even though they were never stored in global storage! Moreover +the extra `store` requirement polluted the entire Diem Framework and many functions had to specify +extra `store` constraints on their type parameters. With the new feature, `Diem::Diem` now +declares `CoinType` to be phantom which avoids the spurious `store` annotations sprinkled over the +code. + +## Description + +### Declaration + +In a struct definition a type parameter can be declared as phantom by adding the `phantom` keyword +before its declaration. If a type parameter is declared as phantom we say it is a phantom type +parameter. When defining a struct, Move's type checker ensures that every phantom type parameter is +either not used inside the struct definition or it is only used as an argument to a phantom type +parameter. + +More formally, if a type is used as an argument to a phantom type parameter we say the type appears +in _phantom position_. With this definition in place, the rule for the correct use of phantom +parameters can be specified as follows: **A phantom type parameter can only appear in phantom +position**. + +The following two examples show valid uses of phantom parameters. In the first one, the parameter +`T1` is not used at all inside the struct definition. In the second one, the parameter `T1` is only +used as an argument to a phantom type parameter. + +``` +struct S1 { f: u64 } + ^^ + Ok: T1 does not appear inside the struct definition + + +struct S2 { f: S1 } + ^^ + Ok: T1 appears in phantom position +``` + +The following code shows examples of violations of the rule: + +``` + +struct S1 { f: T } + ^ + Error: Not a phantom position + +struct S2 { f: T } + +struct S3 { f: S2 } + ^ + Error: Not a phantom position +``` + +### Instantiation + +When instantiating a struct, the arguments to phantom parameters are excluded when deriving the +struct abilities. For example, consider the following code: + +``` +struct S has copy { f: T1 } +struct NoCopy {} +struct HasCopy has copy {} +``` + +Consider now the type `S`. Since `S` is defined with `copy` and all non-phantom +arguments have copy then `S` also has copy. + +### Phantom Type Parameters with Ability Constraints + +Ability constraints and phantom type parameters are orthogonal features in the sense that phantom +parameters can be declared with ability constraints. When instantiating a phantom type parameter +with an ability constraint, the type argument has to satisfy that constraint, even though the +parameter is phantom. For example, the following definition is perfectly valid: + +``` +struct S {} +``` + +The usual restrictions apply and `T` can only be instantiated with arguments having `copy`. diff --git a/vendors/move/changes/7-packages.md b/vendors/move/changes/7-packages.md new file mode 100644 index 000000000..dae0e7179 --- /dev/null +++ b/vendors/move/changes/7-packages.md @@ -0,0 +1,327 @@ +# Packages + +* Status: Implemented in Move 1.5 + +## Introduction + +Packages are a new source feature to allow Move programmers to more easily +re-use code and share it across projects. The Move package system allows +programmers to easily: +* Define a package containing Move code; +* Parameterize a package by named addresses; +* Use a package in Move code and instantiate its named addresses; +* Build packages; and +* Work with a common interface around compiled Move artifacts. + +## Motivation + +Until now, when writing Move you had no easy options of being able to +package Move code into reusable chunks that could be used by others. There +was no common compiled object model or on-disk representation of compiled +Move code and its associated artifacts, e.g., source maps and generated +documentation. And finally, there was no way of easily managing named +addresses that spanned "logical groupings" of Move code. + +The Move package system aims to make these actions easier by providing a +common compiled-object model and access to both compiled bytecode and + associated compilation artifacts along with ways to: +* Declare logical packages of Move code; +* Import and use packages; +* Compile and generate associated compilation artifacts from packages; and +* Manage--expose and instantiate--named addresses in packages. + +## Package Layout and Manifest Syntax + +A Move package source directory contains a `Move.toml` package manifest +file along with a set of subdirectories: + +``` +a_move_package +├── Move.toml (required) +├── sources (required) +├── examples (optional, test & dev mode) +├── scripts (optional) +├── doc_templates (optional) +└── tests (optional, test mode) +``` + +The directories marked `required` _must_ be present in order for the directory +to be considered a Move package and to be compiled. Optional directories can +be present, and if so will be included in the compilation process. Depending on +the mode that the package is built with (`test` or `dev`), the `tests` and +`examples` directories will be included as well. + +The `sources` directory can contain both Move modules and Move scripts (both +transaction scripts and modules containing script functions). The `examples` +directory can hold additional code to be used only for development and/or +tutorial purposes that will not be included when compiled outside `test` or +`dev` mode. + +A `scripts` directory is supported so transaction scripts can be separated +from modules if that is desired by the package author. The `scripts` +directory will always be included for compilation if it is present. +Documentation will be built using any [documentation +templates](../move-prover/doc/user/docgen.md) present in the +`doc_templates` directory. + +### Move.toml + +The Move package manifest is defined within the `Move.toml` file and has the +following syntax. Optional fields are marked with `*`, `+` denotes +one or more elements: + +``` +[package] +name = # e.g., "MoveStdlib" +version = ".." # e.g., "0.1.1" +license* = # e.g., "MIT", "GPL", "Apache 2.0" +authors* = [] # e.g., ["Joe Smith (joesmith@noemail.com)", "Jane Smith (janesmith@noemail.com)"] + +[addresses] # (Optional section) Declares named addresses in this package and instantiates named addresses in the package graph +# One or more lines declaring named addresses in the following format + = "_" | "" # e.g., Std = "_" or Addr = "0xC0FFEECAFE" + +[dependencies] # (Optional section) Paths to dependencies and instantiations or renamings of named addresses from each dependency +# One or more lines declaring dependencies in the following format + = { local = , addr_subst* = { ( = ( | ""))+ } } + +[dev-addresses] # (Optional section) Same as [addresses] section, but only included in "dev" and "test" modes +# One or more lines declaring dev named addresses in the following format + = "_" | "" # e.g., Std = "_" or Addr = "0xC0FFEECAFE" + +[dev-dependencies] # (Optional section) Same as [dependencies] section, but only included in "dev" and "test" modes +# One or more lines declaring dev dependencies in the following format + = { local = , addr_subst* = { ( = ( |
))+ } } +``` + +An example of the most minimal package manifest: + +``` +[package] +name = "AName" +version = "0.0.0" +``` + +An example of a more standard package manifest that also includes the Move +standard library and instantiates the named address `Std` from it with the +address value `0x1`: + +``` +[package] +name = "AName" +version = "0.0.0" +license = "Apache 2.0" + +[addresses] +AddressToBeFilledIn = "_" +SpecifiedAddress = "0xB0B" + +[dependencies] +MoveStdlib = { local = "/move-stdlib", addr_subst = { "Std" = "0x1" } } + +[dev-addresses] # For use when developing this module +AddressToBeFilledIn = "0x101010101" +``` + +Most of the sections in the package manifest are self explanatory, but named +addresses can be a bit difficult to understand so it's worth examining them in +a bit more detail. + +## Named Addresses During Compilation + +Recall that Move has [named addresses](./5-named-addresses.md) and that +named addresses cannot be declared in Move. Because of this, until now +named addresses and their values needed to be passed to the compiler on the +command line. With the Move package system this is no longer needed, and +you can declare named addresses in the package, instantiate other named +addresses in scope, and rename named addresses from other packages within +the Move package system manifest file. Let's go through each of these +individually: + +## Declaration + +Let's say we have a Move module in `example_pkg/sources/A.move` as follows: +```move +module NamedAddr::A { + public fun x(): address { @NamedAddr } +} +``` + +We could in `example_pkg/Move.toml` declare the named address `NamedAddr` in +two different ways. The first: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +NamedAddr = "_" +``` + +Declares `NamedAddr` as a named address in the package `ExamplePkg` and +that _this address can be any valid address value_. Therefore an importing +package can pick the value of the named address `NamedAddr` to be any address +it wishes. Intuitively you can think of this as parameterizing the package +`ExamplePkg` by the named address `NamedAddr`, and the package can then be +instantiated later on by an importing package. + +`NamedAddr` can also be declared as: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +NamedAddr = "0xCAFE" +``` + +which states that the named address `NamedAddr` is exactly `0xCAFE` and cannot be +changed. This is useful so other importing packages can use this named +address without needing to worry about the exact value assigned to it. + +With these two different declaration methods, there are two ways that +information about named addresses can flow in the package graph: +* The former ("unassigned named addresses") allows named address values to flow + from the importation site to the declaration site. +* The latter ("assigned named addresses") allows named address values to flow + from the declaration site upwards in the package graph to usage sites. + +With these two methods for flowing named address information throughout the +package graph the rules around scoping and renaming become important to +understand. + +## Scoping and Renaming of Named Addresses + +A named address `N` in a package `P` is in scope if: +1. It declares a named address `N`; or +2. A package in one of `P`'s transitive dependencies declares the named address + `N` and there is a dependency path in the package graph between between `P` and the + declaring package of `N` with no renaming of `N`. + +Additionally, every named address in a package is exported. Because of this and +the above scoping rules each package can be viewed as coming with a set of +named addresses that will be brought into scope when the package is imported, +e.g., if the `ExamplePkg` package was imported, that importation would bring +into scope the `NamedAddr` named address. Because of this, if `P` imports two +packages `P1` and `P2` both of which declare a named address `N` an issue +arises in `P`: which "`N`" is meant when `N` is referred to in `P`? The one +from `P1` or `P2`? To prevent this ambiguity around which package a named +address is coming from, we enforce that the sets of scopes introduced by all +dependencies in a package are disjoint, and provide a way to _rename named +addresses_ when the package that brings them into scope is imported. + +Renaming a named address when importing can be done as follows in our `P`, +`P1`, and `P2` example above: + +``` +[package] +name = "P" +... +[dependencies] +P1 = { local = "some_path_to_P1", addr_subst = { "P1N" = "N" } } +P2 = { local = "some_path_to_P2" } +``` + +With this renaming `N` refers to the `N` from `P2` and `P1N` will refer to `N` +coming from `P1`: + +``` +module N::A { + public fun x(): address { @P1N } +} +``` + +It is important to note that _renaming is not local_: once a named address `N` +has been renamed to `N2` in a package `P` all packages that import `P` will not +see `N` but only `N2` unless `N` is reintroduced from outside of `P`. This is +why rule (2) in the scoping rules at the start of this section specifies a +"dependency path in the package graph between between `P` and the declaring +package of `N` with no renaming of `N`." + +### Instantiation + +Named addresses can be instantiated multiple times across the package graph as +long as it is always with the same value. It is an error if the same named +address (regardless of renaming) is instantiated with differing values across +the package graph. + +A Move package can only be compiled if all named addresses resolve to a value. +This presents issues if the package wishes to expose an uninstantiated named +address. This is what the `[dev-addresses]` section solves. This section can +set values for named addresses, but cannot introduce any named addresses. +Additionally, only the `[dev-addresses]` in the root package are included in +`dev` mode. For example a root package with the following manifest would not compile +outside of `dev` mode since `NamedAddr` would be uninstantiated: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +NamedAddr = "_" + +[dev-addresses] +NamedAddr = "0xC0FFEE" +``` + +## Usage, Artifacts, and Data Structures + +The Move package system comes with a command line option as part of the Move +CLI `move `. Unless a +particular path is provided, all package commands will run in the current working +directory. The full list of commands and flags for the Move CLI can be found by +running `move --help`. + +### Usage + +A package can be compiled either through the Move CLI commands, or as a library +command in Rust with the function `compile_package`. This will create a +`CompiledPackage` that holds the compiled bytecode along with other compilation +artifacts (source maps, documentation, ABIs) in memory. This `CompiledPackage` +can be converted to an `OnDiskPackage` and vice versa -- the latter being the data of +the `CompiledPackage` laid out in the file system in the following format: + +``` +a_move_package +├── Move.toml +... +└── build + ├── + │   ├── BuildInfo.yaml + │   ├── bytecode_modules + │   │   └── *.mv + │   ├── source_maps + │   │   └── *.mvsm + │ ├── bytecode_scripts + │ │   └── *.mv + │ ├── abis + │ │   ├── *.abi + │ │   └── /*.abi + │   └── sources + │   └── *.move + ... + └── + ├── BuildInfo.yaml + ... + └── sources +``` + +See the `move-package` crate for more information on these data structures and +how to use the Move package system as a Rust library. + +## Future Work + +We intend on adding support for the following features over time: +* Adding a flag to print the named addresses in scope and their values for each + of the dependencies of the package being built. +* Support renaming multiple names from dependencies to one named address, e.g. + the following will not work today, but we'd like to support it: + ``` + ... + [dependencies] + A = { local = "...", addr_subst = { "Addr" = "A" } } + B = { local = "...", addr_subst = { "Addr" = "B" } } + ``` +* Default importation of the Move standard library: currently the Move standard + library must be imported in the package in order to use unit testing + features. diff --git a/vendors/move/crates/benchmarks/.gitignore b/vendors/move/crates/benchmarks/.gitignore new file mode 100644 index 000000000..13a3d7626 --- /dev/null +++ b/vendors/move/crates/benchmarks/.gitignore @@ -0,0 +1,2 @@ +# Criterion puts its benchmark results under the target directory in here, not at the top (workspace) level. +/target/ diff --git a/vendors/move/crates/benchmarks/Cargo.toml b/vendors/move/crates/benchmarks/Cargo.toml new file mode 100644 index 000000000..ef28268d3 --- /dev/null +++ b/vendors/move/crates/benchmarks/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "language-benchmarks" +version = "0.1.0" +authors = ["Diem Association "] +description = "Move language benchmarks" +repository = "https://github.com/diem/diem" +homepage = "https://diem.com" +license = "Apache-2.0" +publish = false +edition = "2021" + +[dependencies] +anyhow = "1.0.52" +criterion = "0.3.4" +criterion-cpu-time = "0.1.0" +move-binary-format = { path = "../move-binary-format" } +once_cell = "1.7.2" +proptest = "1.0.0" + +move-bytecode-verifier = { path = "../move-bytecode-verifier" } +move-compiler = { path = "../move-compiler" } +move-core-types = { path = "../move-core-types" } +move-stdlib = { path = "../move-stdlib" } +move-vm-runtime = { path = "../move-vm/runtime" } +move-vm-test-utils = { path = "../move-vm/test-utils" } +move-vm-types = { path = "../move-vm/types" } + +[[bench]] +name = "vm_benches" +harness = false diff --git a/vendors/move/crates/benchmarks/README.md b/vendors/move/crates/benchmarks/README.md new file mode 100644 index 000000000..271756946 --- /dev/null +++ b/vendors/move/crates/benchmarks/README.md @@ -0,0 +1,34 @@ +# Profiling MoveVM with Instrument +This doc is going to talk about how to run performance benchmarks on macOS. + +## Step 1: Get latest Xcode and open Instrument + +Instrument can be found in Xcode > Open Developer Tool > Instrument. +![](https://i.imgur.com/QCwJBim.png) + + + +## Step 2: Choose a benchmark suite. + +We currently have four local benchmark candidates: +- `executor_benchmark` in `diem/executor` +- `txn_bench` in `diem/language/benchmark` +- `Arith` and `call` benchmark in `diem/language/benchmark` + +The first item is a comprehensive benchmark of diem adapter, executor and storage that generates a block of p2p transactions and tries to execute and commit it to the DiemDB in local storage. The second item is a benchmark of Diem adapter only with a fake executor and an in-memory storage that executes randomly generated p2p transactions. The third item, although it’s still invoking Diem adapter, is mostly testing on the MoveVM’s ability of handling simple arithmetic operations and call stacks. + +## Step 3: Select the running process in Instrument. +Open instrument and create a time profiler project. + +![](https://i.imgur.com/dbLht9f.png) + +Launch the benchmark target in the terminal, and select it in Instrument. + +![](https://i.imgur.com/LU10tZC.jpg) + + +## Step 4: Get analysis! + +Here’s an example trace from running the benchmark + +![](https://i.imgur.com/BAoprNq.jpg) diff --git a/vendors/move/crates/benchmarks/benches/vm_benches.rs b/vendors/move/crates/benchmarks/benches/vm_benches.rs new file mode 100644 index 000000000..3482e15c0 --- /dev/null +++ b/vendors/move/crates/benchmarks/benches/vm_benches.rs @@ -0,0 +1,32 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use criterion::{criterion_group, criterion_main, measurement::Measurement, Criterion}; +use language_benchmarks::{measurement::cpu_time_measurement, move_vm::bench}; + +// +// MoveVM benchmarks +// + +fn arith(c: &mut Criterion) { + bench(c, "arith"); +} + +fn call(c: &mut Criterion) { + bench(c, "call"); +} + +fn natives(c: &mut Criterion) { + bench(c, "natives"); +} + +criterion_group!( + name = vm_benches; + config = cpu_time_measurement(); + targets = arith, + call, + natives +); + +criterion_main!(vm_benches); diff --git a/vendors/move/crates/benchmarks/src/bench.move b/vendors/move/crates/benchmarks/src/bench.move new file mode 100644 index 000000000..fc9b4d205 --- /dev/null +++ b/vendors/move/crates/benchmarks/src/bench.move @@ -0,0 +1,112 @@ +// `cargo bench` will call a public function in this module. +// The Module must be called `Bench` and the set of public functions are callable from the bench (Rust code). +// `benches/transaction.rs` contains the calling code. +// The idea is that you build your scenario with a public entry point and a bunch of private functions as needed. +module 0x1::Bench { + use std::vector; + + // + // Global helpers + // + fun check(check: bool, code: u64) { + if (check) () else abort code + } + + // + // `arith` benchmark + // + public fun arith() { + let i = 0; + // 10000 is the number of loops to make the benchmark run for a couple of minutes, which is an eternity. + // Adjust according to your needs, it's just a reference + while (i < 10000) { + 1; + 10 + 3; + 10; + 7 + 5; + let x = 1; + let y = x + 3; + check(x + y == 5, 10); + i = i + 1; + }; + } + + // + // `call` benchmark + // + public fun call() { + let i = 0; + // 3000 is the number of loops to make the benchmark run for a couple of minutes, which is an eternity. + // Adjust according to your needs, it's just a reference + while (i < 3000) { + let b = call_1(@0x0, 128); + call_2(b); + i = i + 1; + }; + } + + fun call_1(addr: address, val: u64): bool { + let b = call_1_1(&addr); + call_1_2(val, val); + b + } + + fun call_1_1(_addr: &address): bool { + true + } + + fun call_1_2(val1: u64, val2: u64): bool { + val1 == val2 + } + + fun call_2(b: bool) { + call_2_1(b); + check(call_2_2() == 400, 200); + } + + fun call_2_1(b: bool) { + check(b == b, 100) + } + + fun call_2_2(): u64 { + 100 + 300 + } + + // + // `natives` benchmark + // + fun test_vector_ops(x1: T, x2: T): (T, T) { + let v: vector = vector::empty(); + check(vector::length(&v) == 0, 100); + vector::push_back(&mut v, x1); + check(vector::length(&v) == 1, 101); + vector::push_back(&mut v, x2); + check(vector::length(&v) == 2, 102); + vector::swap(&mut v, 0, 1); + x1 = vector::pop_back(&mut v); + check(vector::length(&v) == 1, 103); + x2 = vector::pop_back(&mut v); + check(vector::length(&v) == 0, 104); + vector::destroy_empty(v); + (x1, x2) + } + + fun test_vector() { + test_vector_ops(1u8, 2u8); + test_vector_ops(1u64, 2u64); + test_vector_ops(1u128, 2u128); + test_vector_ops(true, false); + test_vector_ops
(@0x1, @0x2); + test_vector_ops>(vector::empty(), vector::empty()); + } + + public fun natives() { + let i = 0; + // 300 is the number of loops to make the benchmark run for a couple of minutes, which is an eternity. + // Adjust according to your needs, it's just a reference + while (i < 300) { + test_vector(); + i = i + 1; + } + } +} diff --git a/vendors/move/crates/benchmarks/src/lib.rs b/vendors/move/crates/benchmarks/src/lib.rs new file mode 100644 index 000000000..8f6293149 --- /dev/null +++ b/vendors/move/crates/benchmarks/src/lib.rs @@ -0,0 +1,8 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +pub mod measurement; +pub mod move_vm; diff --git a/vendors/move/crates/benchmarks/src/measurement.rs b/vendors/move/crates/benchmarks/src/measurement.rs new file mode 100644 index 000000000..83b10dda9 --- /dev/null +++ b/vendors/move/crates/benchmarks/src/measurement.rs @@ -0,0 +1,14 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use criterion::Criterion; +use criterion_cpu_time::PosixTime; + +pub fn cpu_time_measurement() -> Criterion { + Criterion::default().with_measurement(PosixTime::UserAndSystemTime) +} + +pub fn wall_time_measurement() -> Criterion { + Criterion::default() +} diff --git a/vendors/move/crates/benchmarks/src/move_vm.rs b/vendors/move/crates/benchmarks/src/move_vm.rs new file mode 100644 index 000000000..2f03c7e63 --- /dev/null +++ b/vendors/move/crates/benchmarks/src/move_vm.rs @@ -0,0 +1,107 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use criterion::{measurement::Measurement, Criterion}; +use move_binary_format::CompiledModule; +use move_compiler::{compiled_unit::AnnotatedCompiledUnit, Compiler}; +use move_core_types::{ + account_address::AccountAddress, + identifier::{IdentStr, Identifier}, + language_storage::{ModuleId, CORE_CODE_ADDRESS}, +}; +use move_vm_runtime::move_vm::MoveVM; +use move_vm_test_utils::BlankStorage; +use move_vm_types::gas::UnmeteredGasMeter; +use once_cell::sync::Lazy; +use std::path::PathBuf; + +static MOVE_BENCH_SRC_PATH: Lazy = Lazy::new(|| { + vec![env!("CARGO_MANIFEST_DIR"), "src", "bench.move"] + .into_iter() + .collect() +}); + +/// Entry point for the bench, provide a function name to invoke in Module Bench in bench.move. +pub fn bench(c: &mut Criterion, fun: &str) { + let modules = compile_modules(); + let move_vm = MoveVM::new(move_stdlib::natives::all_natives( + AccountAddress::from_hex_literal("0x1").unwrap(), + move_stdlib::natives::GasParameters::zeros(), + )) + .unwrap(); + execute(c, &move_vm, modules, fun); +} + +// Compile `bench.move` and its dependencies +fn compile_modules() -> Vec { + let mut src_files = move_stdlib::move_stdlib_files(); + src_files.push(MOVE_BENCH_SRC_PATH.to_str().unwrap().to_owned()); + let (_files, compiled_units) = Compiler::from_files( + src_files, + vec![], + move_stdlib::move_stdlib_named_addresses(), + ) + .build_and_report() + .expect("Error compiling..."); + compiled_units + .into_iter() + .map(|unit| match unit { + AnnotatedCompiledUnit::Module(annot_unit) => annot_unit.named_module.module, + AnnotatedCompiledUnit::Script(_) => { + panic!("Expected a module but received a script") + }, + }) + .collect() +} + +// execute a given function in the Bench module +fn execute( + c: &mut Criterion, + move_vm: &MoveVM, + modules: Vec, + fun: &str, +) { + // establish running context + let storage = BlankStorage::new(); + let sender = CORE_CODE_ADDRESS; + let mut session = move_vm.new_session(&storage); + + // TODO: we may want to use a real gas meter to make benchmarks more realistic. + + for module in modules { + let mut mod_blob = vec![]; + module + .serialize(&mut mod_blob) + .expect("Module serialization error"); + session + .publish_module(mod_blob, sender, &mut UnmeteredGasMeter) + .expect("Module must load"); + } + + // module and function to call + let module_id = ModuleId::new(sender, Identifier::new("Bench").unwrap()); + let fun_name = IdentStr::new(fun).unwrap_or_else(|_| panic!("Invalid identifier name {}", fun)); + + // benchmark + c.bench_function(fun, |b| { + b.iter(|| { + session + .execute_function_bypass_visibility( + &module_id, + fun_name, + vec![], + Vec::>::new(), + &mut UnmeteredGasMeter, + ) + .unwrap_or_else(|err| { + panic!( + "{:?}::{} failed with {:?}", + &module_id, + fun, + err.into_vm_status() + ) + }) + }) + }); +} diff --git a/vendors/move/crates/bytecode-interpreter-crypto/Cargo.toml b/vendors/move/crates/bytecode-interpreter-crypto/Cargo.toml new file mode 100644 index 000000000..73bada86d --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-crypto/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "bytecode-interpreter-crypto" +version = "0.1.0" +authors = ["Diem Association "] +publish = false +edition = "2021" +license = "Apache-2.0" + +[dependencies] + +# external dependencies +anyhow = "1.0.71" +curve25519-dalek.workspace = true +ed25519-dalek.workspace = true +sha2.workspace = true +sha3.workspace = true diff --git a/vendors/move/crates/bytecode-interpreter-crypto/src/lib.rs b/vendors/move/crates/bytecode-interpreter-crypto/src/lib.rs new file mode 100644 index 000000000..2bbe1dfc7 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-crypto/src/lib.rs @@ -0,0 +1,102 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This file duplicates the code in the diem-crypto crate to support +//! - native function implementation for the stackless bytecode interpreter, and +//! - decoupling of Move crates from Diem crates. +//! +//! This is expected to be a temporary solution only. Once we properly +//! restructure the stackless interpreter like what we did to the Move VM, +//! native functions will likely be implemented in a Diem crate (most likely +//! diem-framework) and be passed into the VM for execution. In this way we no +//! longer need to worry about depending on diem-crypto. + +use anyhow::{bail, Result}; +use ed25519_dalek::{ + PublicKey as Ed25519PublicKey, Signature as Ed25519Signature, + PUBLIC_KEY_LENGTH as ED25519_PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH as ED25519_SIGNATURE_LENGTH, +}; +use sha2::{Digest, Sha256}; +use sha3::Sha3_256; +use std::cmp::Ordering; + +/// The order of ed25519 as defined in [RFC8032](https://tools.ietf.org/html/rfc8032). +const L: [u8; 32] = [ + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +]; + +// Hash functions +pub fn sha2_256_of(bytes: &[u8]) -> Vec { + Sha256::digest(bytes).to_vec() +} + +pub fn sha3_256_of(bytes: &[u8]) -> Vec { + Sha3_256::digest(bytes).to_vec() +} + +// Ed25519 +fn validate_public_key(bytes: &[u8]) -> bool { + // We need to access the Edwards point which is not directly accessible from + // ed25519_dalek::PublicKey, so we need to do some custom deserialization. + if bytes.len() != ED25519_PUBLIC_KEY_LENGTH { + return false; + } + + let mut bits = [0u8; ED25519_PUBLIC_KEY_LENGTH]; + bits.copy_from_slice(&bytes[..ED25519_PUBLIC_KEY_LENGTH]); + + let compressed = curve25519_dalek::edwards::CompressedEdwardsY(bits); + let point = match compressed.decompress() { + None => return false, + Some(point) => point, + }; + + // Check if the point lies on a small subgroup. This is required + // when using curves with a small cofactor (in ed25519, cofactor = 8). + !point.is_small_order() +} + +pub fn ed25519_deserialize_public_key(bytes: &[u8]) -> Result { + if !validate_public_key(bytes) { + bail!("Invalid public key bytes"); + } + Ok(Ed25519PublicKey::from_bytes(bytes)?) +} + +fn validate_signature(bytes: &[u8]) -> bool { + if bytes.len() != ED25519_SIGNATURE_LENGTH { + return false; + } + for i in (0..32).rev() { + match bytes[32 + i].cmp(&L[i]) { + Ordering::Less => return true, + Ordering::Greater => return false, + _ => (), + } + } + // As this stage S == L which implies a non canonical S. + false +} + +pub fn ed25519_deserialize_signature(bytes: &[u8]) -> Result { + if !validate_signature(bytes) { + bail!("Invalid signature bytes"); + } + Ok(Ed25519Signature::from_bytes(bytes)?) +} + +pub fn ed25519_verify_signature( + key: &Ed25519PublicKey, + sig: &Ed25519Signature, + msg: &[u8], +) -> Result<()> { + if !validate_public_key(&key.to_bytes()) { + bail!("Malleable public key"); + } + if !validate_signature(&sig.to_bytes()) { + bail!("Malleable signature"); + } + Ok(key.verify_strict(msg, sig)?) +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/Cargo.toml b/vendors/move/crates/bytecode-interpreter-testsuite/Cargo.toml new file mode 100644 index 000000000..841d90517 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "bytecode-interpreter-testsuite" +version = "0.1.0" +authors = ["Diem Association "] +publish = false +edition = "2021" +license = "Apache-2.0" + +[dev-dependencies] + +# diem dependencies +move-stackless-bytecode-interpreter.workspace = true +move-command-line-common.workspace = true +move-prover-test-utils.workspace = true +move-stdlib.workspace = true +move-unit-test.workspace = true + +# external dependencies +anyhow = "1.0.71" +datatest-stable.workspace = true + +[[test]] +name = "concrete_check_testsuite" +harness = false + +[dependencies] diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/arithmetics.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/arithmetics.exp new file mode 100644 index 000000000..1fc1059fd --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/arithmetics.exp @@ -0,0 +1,12 @@ +Running Move unit tests +[ PASS ] 0x2::A::add_ok +[ PASS ] 0x2::A::add_overflow +[ PASS ] 0x2::A::div_by_zero +[ PASS ] 0x2::A::div_ok +[ PASS ] 0x2::A::mod_by_zero +[ PASS ] 0x2::A::mod_ok +[ PASS ] 0x2::A::mul_ok +[ PASS ] 0x2::A::mul_overflow +[ PASS ] 0x2::A::sub_ok +[ PASS ] 0x2::A::sub_underflow +Test result: OK. Total tests: 10; passed: 10; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/arithmetics.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/arithmetics.move new file mode 100644 index 000000000..869b3e623 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/arithmetics.move @@ -0,0 +1,61 @@ +module 0x2::A { + #[test] + public fun add_ok(): u8 { + let a = 1 + 2; + a + } + + #[test, expected_failure] + public fun add_overflow(): u8 { + let a = 255 + 1; + a + } + + #[test] + public fun sub_ok(): u64 { + let a = 1 - 1; + a + } + + #[test, expected_failure] + public fun sub_underflow(): u64 { + let a = 1 - 2; + a + } + + #[test] + public fun mul_ok(): u8 { + let a = 2 * 3; + a + } + + #[test, expected_failure] + public fun mul_overflow(): u8 { + let a = 16 * 16; + a + } + + #[test] + public fun div_ok(): u128 { + let a = 5 / 2; + a + } + + #[test, expected_failure] + public fun div_by_zero(): u128 { + let a = 5 / 0; + a + } + + #[test] + public fun mod_ok(): u128 { + let a = 5 % 2; + a + } + + #[test, expected_failure] + public fun mod_by_zero(): u128 { + let a = 5 % 0; + a + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bcs.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bcs.exp new file mode 100644 index 000000000..4096a421a --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bcs.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::bcs_ops +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bcs.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bcs.move new file mode 100644 index 000000000..c6087dbd2 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bcs.move @@ -0,0 +1,38 @@ +module 0x2::A { + use std::bcs; + + #[test] + public fun bcs_ops() { + // address + /* deactivate because of variable address size + let addr = @0x89b9f9d1fadc027cf9532d6f99041522; + let expected_output = x"89b9f9d1fadc027cf9532d6f99041522"; + assert!(bcs::to_bytes(&addr) == expected_output, 8001); + */ + + // bool + let b = true; + let expected_output = x"01"; + assert!(bcs::to_bytes(&b) == expected_output, 8002); + + // u8 + let i = 1u8; + let expected_output = x"01"; + assert!(bcs::to_bytes(&i) == expected_output, 8003); + + // u64 + let i = 1u64; + let expected_output = x"0100000000000000"; + assert!(bcs::to_bytes(&i) == expected_output, 8004); + + // u128 + let i = 1u128; + let expected_output = x"01000000000000000000000000000000"; + assert!(bcs::to_bytes(&i) == expected_output, 8005); + + // vector + let v = x"0f"; + let expected_output = x"010f"; + assert!(bcs::to_bytes(&v) == expected_output, 8006); + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bitwise.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bitwise.exp new file mode 100644 index 000000000..f2bb3f334 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bitwise.exp @@ -0,0 +1,7 @@ +Running Move unit tests +[ PASS ] 0x2::A::bitand +[ PASS ] 0x2::A::bitor +[ PASS ] 0x2::A::bitxor +[ PASS ] 0x2::A::shl +[ PASS ] 0x2::A::shr +Test result: OK. Total tests: 5; passed: 5; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bitwise.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bitwise.move new file mode 100644 index 000000000..22cab2c4b --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/bitwise.move @@ -0,0 +1,31 @@ +module 0x2::A { + #[test] + public fun bitand(): u8 { + let a = 0x1 & 0x2; + a + } + + #[test] + public fun bitor(): u8 { + let a = 0x1 | 0x2; + a + } + + #[test] + public fun bitxor(): u8 { + let a = 0x1 ^ 0x2; + a + } + + #[test] + public fun shl(): u8 { + let a = 0x1 << 2; + a + } + + #[test] + public fun shr(): u8 { + let a = 0x10 >> 2; + a + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/choice.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/choice.exp new file mode 100644 index 000000000..e7da95feb --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/choice.exp @@ -0,0 +1,67 @@ +Running Move unit tests +[ FAIL ] 0x2::A::simple_number_min_range_failure +[ FAIL ] 0x2::A::simple_number_range_failure +[ FAIL ] 0x2::A::vector_choose_min_unsatisfied_predicate +[ PASS ] 0x2::A::vector_choose_success +[ FAIL ] 0x2::A::vector_choose_unsatisfied_predicate + +Test failures: + +Failures in 0x2::A: + +┌── simple_number_min_range_failure ────── +│ error: failed to evaluate expression: enumeration of a non-address type domain is not supported +│ ┌─ tests/concrete_check/choice.move:56:42 +│ │ +│ 56 │ ensures result <= (choose min x: u64 where x >= 4); +│ │ ^^^ +│ +│ error: failed to evaluate expression: unexpected error code +│ ┌─ tests/concrete_check/choice.move:56:17 +│ │ +│ 56 │ ensures result <= (choose min x: u64 where x >= 4); +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ +│ +└────────────────── + + +┌── simple_number_range_failure ────── +│ error: failed to evaluate expression: enumeration of a non-address type domain is not supported +│ ┌─ tests/concrete_check/choice.move:49:38 +│ │ +│ 49 │ ensures result <= (choose x: u64 where x >= 4); +│ │ ^^^ +│ +│ error: failed to evaluate expression: unexpected error code +│ ┌─ tests/concrete_check/choice.move:49:17 +│ │ +│ 49 │ ensures result <= (choose x: u64 where x >= 4); +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ +│ +└────────────────── + + +┌── vector_choose_min_unsatisfied_predicate ────── +│ error: failed to evaluate expression: choose min fails to satisfy a predicate +│ ┌─ tests/concrete_check/choice.move:42:68 +│ │ +│ 42 │ let post choice_min = choose min i in 0..len(result) where result[i] == 3; +│ │ ^^^^^^^^^^^^^^ +│ +│ +└────────────────── + + +┌── vector_choose_unsatisfied_predicate ────── +│ error: failed to evaluate expression: choose fails to satisfy a predicate +│ ┌─ tests/concrete_check/choice.move:29:60 +│ │ +│ 29 │ let post choice = choose i in 0..len(result) where result[i] == 3; +│ │ ^^^^^^^^^^^^^^ +│ +│ +└────────────────── + +Test result: FAILED. Total tests: 5; passed: 1; failed: 4 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/choice.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/choice.move new file mode 100644 index 000000000..030bfa1bf --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/choice.move @@ -0,0 +1,58 @@ +module 0x2::A { + use std::vector; + + #[test] + public fun vector_choose_success(): vector { + let v = vector::empty(); + vector::push_back(&mut v, 1); + vector::push_back(&mut v, 2); + vector::push_back(&mut v, 1); + v + } + + spec vector_choose_success { + let post choice = choose i in 0..len(result) where result[i] == 1; + ensures choice == 0 || choice == 2; + ensures (choose min i in 0..len(result) where result[i] == 1) == 0; + } + + #[test] + public fun vector_choose_unsatisfied_predicate(): vector { + let v = vector::empty(); + vector::push_back(&mut v, 1); + vector::push_back(&mut v, 2); + vector::push_back(&mut v, 1); + v + } + + spec vector_choose_unsatisfied_predicate { + let post choice = choose i in 0..len(result) where result[i] == 3; + } + + #[test] + public fun vector_choose_min_unsatisfied_predicate(): vector { + let v = vector::empty(); + vector::push_back(&mut v, 1); + vector::push_back(&mut v, 2); + vector::push_back(&mut v, 1); + v + } + + spec vector_choose_min_unsatisfied_predicate { + let post choice_min = choose min i in 0..len(result) where result[i] == 3; + } + + #[test] + public fun simple_number_range_failure(): u64 { 1 } + + spec simple_number_range_failure { + ensures result <= (choose x: u64 where x >= 4); + } + + #[test] + public fun simple_number_min_range_failure(): u64 { 1 } + + spec simple_number_min_range_failure { + ensures result <= (choose min x: u64 where x >= 4); + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/comparison.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/comparison.exp new file mode 100644 index 000000000..437f3b48f --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/comparison.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::compare +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/comparison.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/comparison.move new file mode 100644 index 000000000..0bcfd926a --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/comparison.move @@ -0,0 +1,8 @@ +module 0x2::A { + #[test] + public fun compare(): (bool, bool, bool, bool, bool, bool) { + let a = 1; + let b = 2; + (a < b, a <= b, a >= b, a > b, a == b, a != b) + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/destroy.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/destroy.exp new file mode 100644 index 000000000..14fea56e3 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/destroy.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::destroy +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/destroy.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/destroy.move new file mode 100644 index 000000000..46bfd2c07 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/destroy.move @@ -0,0 +1,19 @@ +module 0x2::A { + struct S { + f1: bool, + f2: u64, + } + + #[allow(unused_function)] + fun foo(s: &S): u64 { + s.f2 + } + + #[test] + public fun destroy(): S { + let s = S { f1: true, f2: 42 }; + let p = &s; + let _ = p; + s + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/empty.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/empty.exp new file mode 100644 index 000000000..48c75830b --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/empty.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::do_nothing +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/empty.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/empty.move new file mode 100644 index 000000000..2279f5987 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/empty.move @@ -0,0 +1,4 @@ +module 0x2::A { + #[test] + public fun do_nothing() {} +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/function_call.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/function_call.exp new file mode 100644 index 000000000..f1120823a --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/function_call.exp @@ -0,0 +1,6 @@ +Running Move unit tests +[ PASS ] 0x2::A::call_imm_ref +[ PASS ] 0x2::A::call_mut_ref +[ PASS ] 0x2::A::call_return_mut_ref +[ PASS ] 0x2::A::call_val +Test result: OK. Total tests: 4; passed: 4; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/function_call.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/function_call.move new file mode 100644 index 000000000..a5a63baa0 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/function_call.move @@ -0,0 +1,47 @@ +module 0x2::A { + public fun handle_val(x: u64): u64 { + x + 1 + } + + public fun handle_imm_ref(x: &u64): u64 { + *x + 1 + } + + public fun handle_mut_ref(x: &mut u64) { + *x = 1; + } + + public fun return_mut_ref(x: &mut u64): &mut u64 { + x + } + + #[test] + public fun call_val(): u64 { + let a = 0u64; + handle_val(a) + } + + #[test] + public fun call_imm_ref(): u64 { + let a = 0u64; + let b = &a; + handle_imm_ref(b) + } + + #[test] + public fun call_mut_ref(): u64 { + let a = 0u64; + let b = &mut a; + handle_mut_ref(b); + a + } + + #[test] + public fun call_return_mut_ref(): u64 { + let a = 0u64; + let b = &mut a; + let c = return_mut_ref(b); + handle_mut_ref(c); + a + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/if_else.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/if_else.exp new file mode 100644 index 000000000..30578ec20 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/if_else.exp @@ -0,0 +1,4 @@ +Running Move unit tests +[ PASS ] 0x2::A::if_else_1 +[ PASS ] 0x2::A::if_else_2 +Test result: OK. Total tests: 2; passed: 2; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/if_else.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/if_else.move new file mode 100644 index 000000000..7a790d828 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/if_else.move @@ -0,0 +1,20 @@ +module 0x2::A { + #[test] + public fun if_else_1(): (u64, u64) { + let a = 1; + let b = 2; + let r = if (a > b) { &mut a } else { &mut b }; + *r = 3; + (a, b) + } + + #[test] + public fun if_else_2(): (u64, u64) { + let a = 2; + let b = 1; + let r = if (a > b) { &mut a } else { &mut b }; + *r = 3; + (a, b) + } + +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant.exp new file mode 100644 index 000000000..5f37c1768 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::load_constant +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant.move new file mode 100644 index 000000000..56ead1551 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant.move @@ -0,0 +1,8 @@ +module 0x2::A { + #[test] + public fun load_constant () { + let _a = true; + let _b = 0u8; + let _c = 0x1; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant_number_literal.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant_number_literal.exp new file mode 100644 index 000000000..cfa142534 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant_number_literal.exp @@ -0,0 +1,5 @@ +Running Move unit tests +[ PASS ] 0x2::A::load_constant_number_literal_u128 +[ PASS ] 0x2::A::load_constant_number_literal_u64 +[ PASS ] 0x2::A::load_constant_number_literal_u8 +Test result: OK. Total tests: 3; passed: 3; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant_number_literal.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant_number_literal.move new file mode 100644 index 000000000..4e8006dd4 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/load_constant_number_literal.move @@ -0,0 +1,22 @@ +module 0x2::A { + #[test] + public fun load_constant_number_literal_u8() { + let a = 1_0u8; + let b: u8 = 10; + assert!(a == b, 1); + } + + #[test] + public fun load_constant_number_literal_u64() { + let a = 100_000u64; + let b = 100000; + assert!(a == b, 1); + } + + #[test] + public fun load_constant_number_literal_u128() { + let a = 100_000_000000000000u128; + let b: u128 = 100000000000000000; + assert!(a == b, 1); + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/local_ref.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/local_ref.exp new file mode 100644 index 000000000..404457a9b --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/local_ref.exp @@ -0,0 +1,4 @@ +Running Move unit tests +[ PASS ] 0x2::A::local_imm_ref +[ PASS ] 0x2::A::local_mut_ref +Test result: OK. Total tests: 2; passed: 2; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/local_ref.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/local_ref.move new file mode 100644 index 000000000..87651fe5a --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/local_ref.move @@ -0,0 +1,16 @@ +module 0x2::A { + #[test] + public fun local_imm_ref(): u64 { + let a = 0; + let b = &a; + *b + } + + #[test] + public fun local_mut_ref(): u64 { + let a = 0; + let b = &mut a; + *b = 1; + a + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/loop.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/loop.exp new file mode 100644 index 000000000..be28cc6e9 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/loop.exp @@ -0,0 +1,2 @@ +Running Move unit tests +Test result: OK. Total tests: 0; passed: 0; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/loop.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/loop.move new file mode 100644 index 000000000..81263623f --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/loop.move @@ -0,0 +1,20 @@ +module 0x2::A { + // #[test] + public fun loop_ind_var() { + let i = 0; + while (i < 10) { + i = i + 1; + }; + } + + // #[test] + public fun loop_ind_ref() { + let i = 0; + let p = &mut i; + while (*p < 10) { + *p = *p + 1; + }; + } + + // TODO(mengxu): needs to fill the havoc-ed value +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/pack_unpack.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/pack_unpack.exp new file mode 100644 index 000000000..2552ef2f1 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/pack_unpack.exp @@ -0,0 +1,4 @@ +Running Move unit tests +[ PASS ] 0x2::A::pack +[ PASS ] 0x2::A::unpack +Test result: OK. Total tests: 2; passed: 2; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/pack_unpack.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/pack_unpack.move new file mode 100644 index 000000000..910546f67 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/pack_unpack.move @@ -0,0 +1,20 @@ +module 0x2::A { + struct S { + f1: bool, + f2: u64, + } + + #[test] + public fun pack(): S { + S { f1: true, f2: 1 } + } + + #[test] + public fun unpack(): (bool, u64) { + let s = S { f1: true, f2: 1 }; + let x1: bool; + let x2: u64; + S { f1: x1, f2: x2 } = s; + (x1, x2) + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/arithmetics.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/arithmetics.exp new file mode 100644 index 000000000..837a47506 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/arithmetics.exp @@ -0,0 +1,31 @@ +Running Move unit tests +[ FAIL ] 0x2::A::check_arithmetics_div0 +[ FAIL ] 0x2::A::check_arithmetics_mod0 +[ PASS ] 0x2::A::check_arithmetics_ok + +Test failures: + +Failures in 0x2::A: + +┌── check_arithmetics_div0 ────── +│ error: failed to evaluate expression: unexpected error code +│ ┌─ tests/concrete_check/property/arithmetics.move:17:20 +│ │ +│ 17 │ assert 5 / 0 == 1; +│ │ ^^^^^^^^^^ +│ +│ +└────────────────── + + +┌── check_arithmetics_mod0 ────── +│ error: failed to evaluate expression: unexpected error code +│ ┌─ tests/concrete_check/property/arithmetics.move:24:20 +│ │ +│ 24 │ assert 5 % 0 == 1; +│ │ ^^^^^^^^^^ +│ +│ +└────────────────── + +Test result: FAILED. Total tests: 3; passed: 1; failed: 2 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/arithmetics.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/arithmetics.move new file mode 100644 index 000000000..261b66736 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/arithmetics.move @@ -0,0 +1,27 @@ +module 0x2::A { + #[test] + public fun check_arithmetics_ok() { + spec { + // there is no overflow/underflow in spec expressions + assert 255u8 + 1u64 == 256u128; + assert 1u8 - 2u64 < 0; + assert 255u8 * 255u8 == 255u128 * 255u128; + assert 5 / 2 == 2; + assert 5 % 2 == 1; + }; + } + + #[test] + public fun check_arithmetics_div0() { + spec { + assert 5 / 0 == 1; + }; + } + + #[test] + public fun check_arithmetics_mod0() { + spec { + assert 5 % 0 == 1; + }; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/basics.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/basics.exp new file mode 100644 index 000000000..79084579d --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/basics.exp @@ -0,0 +1,32 @@ +Running Move unit tests +[ FAIL ] 0x2::A::check_const_fail +[ PASS ] 0x2::A::check_const_pass +[ FAIL ] 0x2::A::check_local_fail +[ PASS ] 0x2::A::check_local_pass + +Test failures: + +Failures in 0x2::A: + +┌── check_const_fail ────── +│ error: property does not hold +│ ┌─ tests/concrete_check/property/basics.move:12:20 +│ │ +│ 12 │ assert false; +│ │ ^^^^^ +│ +│ +└────────────────── + + +┌── check_local_fail ────── +│ error: property does not hold +│ ┌─ tests/concrete_check/property/basics.move:29:20 +│ │ +│ 29 │ assert a; +│ │ ^ +│ +│ +└────────────────── + +Test result: FAILED. Total tests: 4; passed: 2; failed: 2 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/basics.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/basics.move new file mode 100644 index 000000000..416a525dd --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/basics.move @@ -0,0 +1,33 @@ +module 0x2::A { + #[test] + public fun check_const_pass() { + spec { + assert true; + }; + } + + #[test] + public fun check_const_fail() { + spec { + assert false; + }; + } + + #[test] + public fun check_local_pass(): bool { + let a = true; + spec { + assert a; + }; + a + } + + #[test] + public fun check_local_fail(): bool { + let a = false; + spec { + assert a; + }; + a + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/bitwise.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/bitwise.exp new file mode 100644 index 000000000..6c2d609b3 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/bitwise.exp @@ -0,0 +1,25 @@ +Running Move unit tests +[ FAIL ] 0x2::A::check_bitwise_fail +[ PASS ] 0x2::A::check_bitwise_ok + +Test failures: + +Failures in 0x2::A: + +┌── check_bitwise_fail ────── +│ error: property does not hold +│ ┌─ tests/concrete_check/property/bitwise.move:14:20 +│ │ +│ 14 │ assert 0x1u128 ^ 0x2 != 0x3u64; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^ +│ +│ error: property does not hold +│ ┌─ tests/concrete_check/property/bitwise.move:15:20 +│ │ +│ 15 │ assert 0x100u64 >> 16 != 0; +│ │ ^^^^^^^^^^^^^^^^^^^ +│ +│ +└────────────────── + +Test result: FAILED. Total tests: 2; passed: 1; failed: 1 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/bitwise.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/bitwise.move new file mode 100644 index 000000000..a61f9af99 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/bitwise.move @@ -0,0 +1,18 @@ +module 0x2::A { + #[test] + public fun check_bitwise_ok() { + spec { + assert 0x1u8 & 0x2u64 == 0u128; + assert 0x1u128 | 0x2u64 == 0x3u8; + assert 0x1u8 << 8 == 0x100; + }; + } + + #[test] + public fun check_bitwise_fail() { + spec { + assert 0x1u128 ^ 0x2 != 0x3u64; + assert 0x100u64 >> 16 != 0; + }; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/boolean.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/boolean.exp new file mode 100644 index 000000000..a91fe6501 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/boolean.exp @@ -0,0 +1,19 @@ +Running Move unit tests +[ FAIL ] 0x2::A::check_boolean_fail +[ PASS ] 0x2::A::check_boolean_ok + +Test failures: + +Failures in 0x2::A: + +┌── check_boolean_fail ────── +│ error: property does not hold +│ ┌─ tests/concrete_check/property/boolean.move:13:20 +│ │ +│ 13 │ assert true ==> false; +│ │ ^^^^^^^^^^^^^^ +│ +│ +└────────────────── + +Test result: FAILED. Total tests: 2; passed: 1; failed: 1 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/boolean.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/boolean.move new file mode 100644 index 000000000..b5d71d43b --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/boolean.move @@ -0,0 +1,16 @@ +module 0x2::A { + #[test] + public fun check_boolean_ok() { + spec { + assert true && false == false; + assert true || false == true; + }; + } + + #[test] + public fun check_boolean_fail() { + spec { + assert true ==> false; + }; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_move.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_move.exp new file mode 100644 index 000000000..1a2f4a264 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_move.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::check_call_move +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_move.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_move.move new file mode 100644 index 000000000..95c27226c --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_move.move @@ -0,0 +1,33 @@ +module 0x2::A { + struct S1 has copy, drop { + f1: bool, + f2: u64, + } + + struct S2 has copy, drop { + f1: bool, + f2: T, + } + + #[allow(unused_function)] + fun move_plain(s: &S1): u64 { + s.f2 + } + + #[allow(unused_function)] + fun move_generic(s: &S2): T { + *&s.f2 + } + + #[test] + public fun check_call_move() { + let s1 = S1 { f1: true, f2: 42 }; + let s2 = S2 { f1: false, f2: s1 }; + let p1 = &s2.f2; + let p2 = &s2; + spec { + assert move_plain(p1) == 42; + assert move_generic(p2) == s1; + }; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_spec.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_spec.exp new file mode 100644 index 000000000..33d5251c4 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_spec.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::check_call_spec +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_spec.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_spec.move new file mode 100644 index 000000000..3af06a256 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/call_spec.move @@ -0,0 +1,31 @@ +module 0x2::A { + struct S1 has copy, drop { + f1: bool, + f2: u64, + } + + struct S2 has copy, drop { + f1: bool, + f2: T, + } + + spec fun spec_plain(s: S1): u64 { + s.f2 + } + + spec fun spec_generic(s: S2): T { + s.f2 + } + + #[test] + public fun check_call_spec() { + let s1 = S1 { f1: true, f2: 42 }; + let s2 = S2 { f1: false, f2: s1 }; + let p1 = &s2.f2; + let p2 = &s2; + spec { + assert spec_plain(p1) == 42; + assert spec_generic(p2) == s1; + }; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/lambda.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/lambda.exp new file mode 100644 index 000000000..57f195339 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/lambda.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::check_lambda +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/lambda.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/lambda.move new file mode 100644 index 000000000..71dddc672 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/lambda.move @@ -0,0 +1,16 @@ +module 0x2::A { + #[test] + public fun check_lambda() { + spec { + assert f2() == 2; + }; + } + spec module { + fun f1(f: |u64| u64): u64 { + f(1u64) + } + fun f2(): num { + f1(|x| x + 1) + } + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/struct.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/struct.exp new file mode 100644 index 000000000..9243ecbb2 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/struct.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::check_struct +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/struct.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/struct.move new file mode 100644 index 000000000..100262ec2 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/struct.move @@ -0,0 +1,18 @@ +module 0x2::A { + struct S has drop { + f1: bool, + f2: u64, + } + + #[test] + public fun check_struct() { + let a = S { f1: true, f2: 42 }; + let b = S { f1: true, f2: 0 }; + spec { + assert a != b; + assert a.f1 == b.f1; + assert a == update_field(b, f2, 42); + assert b != S { f1: false, f2: 0 }; + }; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/vector.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/vector.exp new file mode 100644 index 000000000..4e6547667 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/vector.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::check_vector +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/vector.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/vector.move new file mode 100644 index 000000000..8a91436f1 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/property/vector.move @@ -0,0 +1,27 @@ +module 0x2::A { + use std::vector; + + #[test] + public fun check_vector() { + let a = vector::empty(); + let b = vector::empty(); + spec { + assert len(a) == 0; + assert a == vec(); + }; + + vector::push_back(&mut a, 42u128); + vector::push_back(&mut b, 0u128); + spec { + assert len(a) == 1; + assert a == vec(42); + assert a[0] == 42; + assert contains(a, 42); + assert index_of(a, 42) == 0; + assert update(b, 0, 42) == a; + assert concat(a, b) == concat(vec(42), vec(0)); + assert in_range(a, 0); + assert !in_range(b, 2); + }; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/quantifier.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/quantifier.exp new file mode 100644 index 000000000..eea1d1a1d --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/quantifier.exp @@ -0,0 +1,49 @@ +Running Move unit tests +[ FAIL ] 0x2::A::init_vector_failure +[ PASS ] 0x2::A::init_vector_success + +Test failures: + +Failures in 0x2::A: + +┌── init_vector_failure ────── +│ error: failed to evaluate expression: enumeration of a non-address type domain is not supported +│ ┌─ tests/concrete_check/quantifier.move:27:27 +│ │ +│ 27 │ ensures exists i: u64 where (i == len(result) - 1): result[i] == 1; +│ │ ^^^ +│ +│ error: failed to evaluate expression: unexpected error code +│ ┌─ tests/concrete_check/quantifier.move:27:17 +│ │ +│ 27 │ ensures exists i: u64 where (i == len(result) - 1): result[i] == 1; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ +│ error: failed to evaluate expression: enumeration of a non-address type domain is not supported +│ ┌─ tests/concrete_check/quantifier.move:28:27 +│ │ +│ 28 │ ensures exists i: u64: (i == len(result) - 1) ==> result[i] == 1; +│ │ ^^^ +│ +│ error: failed to evaluate expression: unexpected error code +│ ┌─ tests/concrete_check/quantifier.move:28:17 +│ │ +│ 28 │ ensures exists i: u64: (i == len(result) - 1) ==> result[i] == 1; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ +│ error: failed to evaluate expression: enumeration of a non-address type domain is not supported +│ ┌─ tests/concrete_check/quantifier.move:29:27 +│ │ +│ 29 │ ensures exists i: u64: result[i] == 1; +│ │ ^^^ +│ +│ error: failed to evaluate expression: unexpected error code +│ ┌─ tests/concrete_check/quantifier.move:29:17 +│ │ +│ 29 │ ensures exists i: u64: result[i] == 1; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ +│ +└────────────────── + +Test result: FAILED. Total tests: 2; passed: 1; failed: 1 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/quantifier.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/quantifier.move new file mode 100644 index 000000000..aeff92fdd --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/quantifier.move @@ -0,0 +1,31 @@ +module 0x2::A { + use std::vector; + + #[test] + public fun init_vector_success(): vector { + let v = vector::empty(); + vector::push_back(&mut v, 1); + vector::push_back(&mut v, 2); + v + } + + spec init_vector_success { + ensures forall num in result: num > 0; + ensures exists num in result: num == 2; + ensures exists i in 0..len(result): result[i] == 1; + } + + #[test] + public fun init_vector_failure(): vector { + let v = vector::empty(); + vector::push_back(&mut v, 1); + vector::push_back(&mut v, 2); + v + } + + spec init_vector_failure { + ensures exists i: u64 where (i == len(result) - 1): result[i] == 1; + ensures exists i: u64: (i == len(result) - 1) ==> result[i] == 1; + ensures exists i: u64: result[i] == 1; + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/return_mut_ref.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/return_mut_ref.exp new file mode 100644 index 000000000..6fe1a0517 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/return_mut_ref.exp @@ -0,0 +1,5 @@ +Running Move unit tests +[ PASS ] 0x2::A::return_ref_path +[ PASS ] 0x2::A::return_ref_path_vec_1 +[ PASS ] 0x2::A::return_ref_root +Test result: OK. Total tests: 3; passed: 3; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/return_mut_ref.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/return_mut_ref.move new file mode 100644 index 000000000..93d1d22d6 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/return_mut_ref.move @@ -0,0 +1,63 @@ +module 0x2::A { + use std::vector; + + struct X has copy, drop { value: u64 } + struct Y has copy, drop { value: u64 } + struct Z has copy, drop { value: u64, x: X } + struct V has copy, drop { is: vector, ts: vector } + + // Return reference with different root + fun return_ref_different_root(cond: bool, x: &mut X, y: &mut Y): &mut u64 { + if (cond) &mut x.value else &mut y.value + } + + #[test] + public fun return_ref_root(): (X, Y) { + let x = X { value: 1 }; + let y = Y { value: 2 }; + let p = return_ref_different_root(true, &mut x, &mut y); + *p = 5; + let q = return_ref_different_root(false, &mut x, &mut y); + *q = 6; + (x, y) + } + + // Return reference with different path + fun return_ref_different_path(cond: bool, z: &mut Z): &mut u64 { + if (cond) &mut z.value else &mut z.x.value + } + + #[test] + public fun return_ref_path(): (Z, Z) { + let z1 = Z { value: 1, x: X { value: 2 } }; + let p = return_ref_different_path(true, &mut z1); + *p = 5; + let z2 = Z { value: 1, x: X { value: 2 } }; + let q = return_ref_different_path(false, &mut z2); + *q = 6; + (z1, z2) + } + + // Return reference with different path in vec + fun return_ref_different_path_vec(cond: bool, v: &mut V, i1: u64, i2: u64): &mut u64 { + if (cond) { + vector::borrow_mut(&mut v.is, i1) + } else { + vector::borrow_mut(&mut v.is, i2) + } + } + + #[test] + public fun return_ref_path_vec_1(): V { + let is = vector::empty(); + let ts = vector::empty(); + vector::push_back(&mut is, 1); + vector::push_back(&mut is, 2); + let v = V { is, ts }; + let p = return_ref_different_path_vec(true, &mut v, 0, 1); + *p = 5; + let q = return_ref_different_path_vec(false, &mut v, 0, 1); + *q = 6; + v + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/vector.exp b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/vector.exp new file mode 100644 index 000000000..98bef1228 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/vector.exp @@ -0,0 +1,3 @@ +Running Move unit tests +[ PASS ] 0x2::A::vector_ops +Test result: OK. Total tests: 1; passed: 1; failed: 0 diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/vector.move b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/vector.move new file mode 100644 index 000000000..216d4ab21 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check/vector.move @@ -0,0 +1,35 @@ +module 0x2::A { + use std::vector; + + struct Foo has drop {} + struct Bar {} + + fun test_natives(x1: T, x2: T): (T, T) { + let v: vector = vector::empty(); + assert!(vector::length(&v) == 0, 100); + vector::push_back(&mut v, x1); + assert!(vector::length(&v) == 1, 101); + vector::push_back(&mut v, x2); + assert!(vector::length(&v) == 2, 102); + vector::swap(&mut v, 0, 1); + x1 = vector::pop_back(&mut v); + assert!(vector::length(&v) == 1, 103); + x2 = vector::pop_back(&mut v); + assert!(vector::length(&v) == 0, 104); + vector::destroy_empty(v); + (x1, x2) + } + + #[test] + public fun vector_ops() { + test_natives(1u8, 2u8); + test_natives(1u64, 2u64); + test_natives(1u128, 2u128); + test_natives(true, false); + test_natives
(@0x1, @0x2); + + test_natives>(vector::empty(), vector::empty()); + test_natives(Foo {}, Foo {}); + (Bar {}, Bar {}) = test_natives(Bar {}, Bar {}); + } +} diff --git a/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check_testsuite.rs b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check_testsuite.rs new file mode 100644 index 000000000..329ac0773 --- /dev/null +++ b/vendors/move/crates/bytecode-interpreter-testsuite/tests/concrete_check_testsuite.rs @@ -0,0 +1,40 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use std::{env, path::Path}; + +use move_command_line_common::{env::read_bool_env_var, testing::EXP_EXT}; +use move_prover_test_utils::baseline_test::verify_or_update_baseline; +use move_stdlib::move_stdlib_files; +use move_unit_test::UnitTestingConfig; + +fn test_runner(path: &Path) -> datatest_stable::Result<()> { + env::set_var("NO_COLOR", "1"); + + let source_files = vec![path.to_str().unwrap().to_owned()]; + let config = UnitTestingConfig { + gas_limit: Some(5000), + num_threads: 1, + source_files, + dep_files: move_stdlib_files(), + check_stackless_vm: true, + verbose: read_bool_env_var("VERBOSE"), + named_address_values: move_stdlib::move_stdlib_named_addresses() + .into_iter() + .collect(), + + ..UnitTestingConfig::default_with_bound(None) + }; + + let test_plan = config.build_test_plan().unwrap(); + let mut buffer = vec![]; + config.run_and_report_unit_tests(test_plan, None, None, &mut buffer)?; + let output = String::from_utf8(buffer)?; + + let baseline_path = path.with_extension(EXP_EXT); + verify_or_update_baseline(&baseline_path, &output)?; + Ok(()) +} + +datatest_stable::harness!(test_runner, "tests/concrete_check", r".*\.move$"); diff --git a/vendors/move/crates/bytecode-verifier-libfuzzer/.gitignore b/vendors/move/crates/bytecode-verifier-libfuzzer/.gitignore new file mode 100644 index 000000000..a0925114d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-libfuzzer/.gitignore @@ -0,0 +1,3 @@ +target +corpus +artifacts diff --git a/vendors/move/crates/bytecode-verifier-libfuzzer/Cargo.toml b/vendors/move/crates/bytecode-verifier-libfuzzer/Cargo.toml new file mode 100644 index 000000000..23ba1eb8c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-libfuzzer/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "bytecode-verifier-libfuzzer" +version = "0.0.0" +authors = ["Diem Association "] +license = "Apache-2.0" +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys.workspace = true +arbitrary.workspace = true +move-bytecode-verifier.workspace = true +move-core-types = { workspace = true, features = ["fuzzing"] } +move-binary-format = { workspace = true, features = ["fuzzing"] } + +# Prevent this from interfering with workspaces +#[workspace] +#members = ["."] + +[[bin]] +name = "code_unit" +path = "fuzz_targets/code_unit.rs" +test = false +doc = false + +[[bin]] +name = "compiled_module" +path = "fuzz_targets/compiled_module.rs" +test = false +doc = false + +[[bin]] +name = "mixed" +path = "fuzz_targets/mixed.rs" +test = false +doc = false diff --git a/vendors/move/crates/bytecode-verifier-libfuzzer/README.md b/vendors/move/crates/bytecode-verifier-libfuzzer/README.md new file mode 100644 index 000000000..633a4797a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-libfuzzer/README.md @@ -0,0 +1,4 @@ +See the [Rust fuzzing book](https://rust-fuzz.github.io/book/) +for how to use the fuzz targets in this directory. Notice that +`cargo +nightly fuzz run ` need to be executed in the parent +directory; nightly is required. diff --git a/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/code_unit.rs b/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/code_unit.rs new file mode 100644 index 000000000..7548af284 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/code_unit.rs @@ -0,0 +1,83 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![no_main] +use move_binary_format::file_format::{ + empty_module, AbilitySet, CodeUnit, Constant, FieldDefinition, FunctionDefinition, + FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, + SignatureIndex, + SignatureToken::{Address, Bool, U128, U64}, + StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, TypeSignature, + Visibility, +}; +use move_core_types::{account_address::AccountAddress, identifier::Identifier}; +use std::str::FromStr; + +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|code_unit: CodeUnit| { + let mut module = empty_module(); + module.version = 5; + + module.struct_handles.push(StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + abilities: AbilitySet::ALL, + type_parameters: vec![], + }); + + let fun_handle = FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + parameters: SignatureIndex(0), + return_: SignatureIndex(1), + type_parameters: vec![], + }; + + module.function_handles.push(fun_handle); + + module.signatures.pop(); + module.signatures.push(Signature(vec![ + Address, U64, Address, Address, U128, Address, U64, U64, U64, + ])); + module.signatures.push(Signature(vec![])); + module + .signatures + .push(Signature(vec![Address, Bool, Address])); + + module.identifiers.extend( + vec![ + Identifier::from_str("zf_hello_world").unwrap(), + Identifier::from_str("awldFnU18mlDKQfh6qNfBGx8X").unwrap(), + Identifier::from_str("aQPwJNHyAHpvJ").unwrap(), + Identifier::from_str("aT7ZphKTrKcYCwCebJySrmrKlckmnL5").unwrap(), + Identifier::from_str("arYpsFa2fvrpPJ").unwrap(), + ] + .into_iter(), + ); + module.address_identifiers.push(AccountAddress::random()); + + module.constant_pool.push(Constant { + type_: Address, + data: AccountAddress::ZERO.into_bytes().to_vec(), + }); + + module.struct_defs.push(StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex::new(3), + signature: TypeSignature(Address), + }]), + }); + + let fun_def = FunctionDefinition { + code: Some(code_unit), + function: FunctionHandleIndex(0), + visibility: Visibility::Public, + is_entry: false, + acquires_global_resources: vec![], + }; + + module.function_defs.push(fun_def); + let _ = move_bytecode_verifier::verify_module_unmetered(&module); +}); diff --git a/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/compiled_module.rs b/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/compiled_module.rs new file mode 100644 index 000000000..ea2859b19 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/compiled_module.rs @@ -0,0 +1,10 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![no_main] +use libfuzzer_sys::fuzz_target; +use move_binary_format::file_format::CompiledModule; + +fuzz_target!(|module: CompiledModule| { + let _ = move_bytecode_verifier::verify_module_unmetered(&module); +}); diff --git a/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/mixed.rs b/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/mixed.rs new file mode 100644 index 000000000..fb2bc6edc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-libfuzzer/fuzz_targets/mixed.rs @@ -0,0 +1,97 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![no_main] +use move_binary_format::file_format::{ + empty_module, AbilitySet, Bytecode, CodeUnit, Constant, FieldDefinition, FunctionDefinition, + FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, + SignatureIndex, SignatureToken, + SignatureToken::{Address, Bool}, + StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, TypeSignature, + Visibility, +}; +use move_core_types::{account_address::AccountAddress, identifier::Identifier}; +use std::str::FromStr; + +use arbitrary::Arbitrary; +use libfuzzer_sys::fuzz_target; + +#[derive(Arbitrary, Debug)] +struct Mixed { + code: Vec, + abilities: AbilitySet, + param_types: Vec, + return_type: Option, +} + +fuzz_target!(|mix: Mixed| { + let mut module = empty_module(); + module.version = 5; + + module.struct_handles.push(StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + abilities: mix.abilities, + type_parameters: vec![], + }); + + let fun_handle = FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + parameters: SignatureIndex(0), + return_: SignatureIndex(1), + type_parameters: vec![], + }; + + module.function_handles.push(fun_handle); + + module.signatures.pop(); + module.signatures.push(Signature(mix.param_types)); + module.signatures.push(Signature( + mix.return_type.map(|s| vec![s]).unwrap_or_default(), + )); + module + .signatures + .push(Signature(vec![Address, Bool, Address])); + + module.identifiers.extend( + vec![ + Identifier::from_str("zf_hello_world").unwrap(), + Identifier::from_str("awldFnU18mlDKQfh6qNfBGx8X").unwrap(), + Identifier::from_str("aQPwJNHyAHpvJ").unwrap(), + Identifier::from_str("aT7ZphKTrKcYCwCebJySrmrKlckmnL5").unwrap(), + Identifier::from_str("arYpsFa2fvrpPJ").unwrap(), + ] + .into_iter(), + ); + module.address_identifiers.push(AccountAddress::random()); + + module.constant_pool.push(Constant { + type_: Address, + data: AccountAddress::ZERO.into_bytes().to_vec(), + }); + + module.struct_defs.push(StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex::new(3), + signature: TypeSignature(Address), + }]), + }); + + let code_unit = CodeUnit { + code: mix.code, + locals: SignatureIndex(0), + }; + + let fun_def = FunctionDefinition { + code: Some(code_unit), + function: FunctionHandleIndex(0), + visibility: Visibility::Public, + is_entry: false, + acquires_global_resources: vec![], + }; + + module.function_defs.push(fun_def); + let _ = move_bytecode_verifier::verify_module_unmetered(&module); +}); diff --git a/vendors/move/crates/bytecode-verifier-tests/Cargo.toml b/vendors/move/crates/bytecode-verifier-tests/Cargo.toml new file mode 100644 index 000000000..8f09b316f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "bytecode-verifier-tests" +version = "0.1.0" +authors = ["Diem Association "] +description = "Diem bytecode verifier tests" +repository = "https://github.com/diem/diem" +homepage = "https://diem.com" +license = "Apache-2.0" +publish = false +edition = "2021" + +[dev-dependencies] +petgraph.workspace = true +proptest.workspace = true +fail = { workspace = true, features = ["failpoints"] } +hex.workspace = true + +invalid-mutations.workspace = true +move-binary-format = { workspace = true, features = ["fuzzing"] } +move-bytecode-verifier.workspace = true +move-core-types.workspace = true +move-vm-config.workspace = true + +[features] +fuzzing = ["move-binary-format/fuzzing"] + +[dependencies] diff --git a/vendors/move/crates/bytecode-verifier-tests/METER_TESTING.md b/vendors/move/crates/bytecode-verifier-tests/METER_TESTING.md new file mode 100644 index 000000000..2f1865f6e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/METER_TESTING.md @@ -0,0 +1,5 @@ +This testsuite can be run in a specific way to print the time until a 'complex' program is detected or accepted. Call as in: + +``` +cargo test --release -- --nocapture 1>/dev/null +``` diff --git a/vendors/move/crates/bytecode-verifier-tests/src/lib.rs b/vendors/move/crates/bytecode-verifier-tests/src/lib.rs new file mode 100644 index 000000000..211d2cd3a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/lib.rs @@ -0,0 +1,11 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +#[cfg(test)] +pub mod support; + +#[cfg(test)] +pub mod unit_tests; diff --git a/vendors/move/crates/bytecode-verifier-tests/src/support/mod.rs b/vendors/move/crates/bytecode-verifier-tests/src/support/mod.rs new file mode 100644 index 000000000..5b55cfc59 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/support/mod.rs @@ -0,0 +1,36 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::{ + file_format::{ + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, IdentifierIndex, + ModuleHandleIndex, SignatureIndex, + }, + CompiledModule, +}; + +/// Create a dummy module to wrap the bytecode program in local@code +pub fn dummy_procedure_module(code: Vec) -> CompiledModule { + let mut module = empty_module(); + let code_unit = CodeUnit { + code, + ..Default::default() + }; + let fun_def = FunctionDefinition { + code: Some(code_unit), + ..Default::default() + }; + + let fun_handle = FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }; + + module.function_handles.push(fun_handle); + module.function_defs.push(fun_def); + module +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/ability_field_requirements_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/ability_field_requirements_tests.rs new file mode 100644 index 000000000..08bbdca20 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/ability_field_requirements_tests.rs @@ -0,0 +1,14 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::file_format::CompiledModule; +use move_bytecode_verifier::ability_field_requirements; +use proptest::prelude::*; + +proptest! { + #[test] + fn valid_ability_transitivity(module in CompiledModule::valid_strategy(20)) { + prop_assert!(ability_field_requirements::verify_module(&module).is_ok()); + } +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/binary_samples.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/binary_samples.rs new file mode 100644 index 000000000..2c506070c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/binary_samples.rs @@ -0,0 +1,77 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Tests in here are based on binary representation of modules taken from production. Those tests +//! may fail over time if the representation becomes out of date, then they can be removed. +//! Right now the serve to calibrate the metering working as expected. Those tests represent +//! cases which we want to continue to succeed. + +use crate::unit_tests::production_config; +use move_binary_format::{errors::VMResult, CompiledModule}; +use move_bytecode_verifier::{meter::BoundMeter, verifier}; + +#[allow(unused)] +fn run_binary_test(name: &str, bytes: &str) -> VMResult<()> { + let bytes = hex::decode(bytes).expect("invalid hex string"); + let m = CompiledModule::deserialize_with_defaults(&bytes).expect("invalid module"); + let config = production_config(); + let mut meter = BoundMeter::new(&config); + verifier::verify_module_with_config_for_test(name, &config, &m, &mut meter) +} + +#[test] +fn sample_price_oracle() { + let code = + "a11ceb0b050000000c01001602162003368a0104c0011405d401a80607fc07f90308f50b6006d50c9b3210f03e770ae73f170cfe3f951e0d935e060000010101020103010401050006020702080209020a000b0800000c0800080d070004170402030100010318070009190700071c0700000e000100000f0201010000100201010000110302000012030200001304020000140506000015050600080f080900071d0a0100081e080900071f0a0b0007200a010006210c01000122020f01000123020c01000424110b020300042511120203000a261314000527020f0100022803180004290219020304092a1a1b00032b1a0f00042c1c02020302020e0e0e0f0e10101110130e1016111615101810020608020201030001060c02060c0304030103010203010908060303080603010301030106080201080601060806010101020502060800080508040802010900010804020804080502060b0302090009010900010609010208050301080202080406080102080403ae010a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a02080508000708000a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050105010b030209000901010a0201080503070b0302090009010900090193010508000708000a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a02080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805010708000b03030101010301030103010b01030101010301030103010c70726963655f6f7261636c6504636f696e067369676e657206737472696e67057461626c6509747970655f696e666f046d617468036936340570726963651070726963655f6964656e74696669657204707974681250726963654964656e7469666965724d61700e54657374507269636553746f72650550726963650c666f726d61745f7072696365096765745f7072696365126765745f70726963655f666f725f746573740a696e697469616c697a6512696e697469616c697a655f746573746e6574127365745f7468726573686f6c645f73656373107369676e65645f7536345f6d696e75730f7369676e65645f7536345f706c757304696e666f055461626c6506537472696e670f50726963654964656e7469666965720e7468726573686f6c645f736563730b70726963655f7461626c6503493634196765745f6d61676e69747564655f69665f706f736974697665086765745f6578706f0f6765745f69735f6e65676174697665196765745f6d61676e69747564655f69665f6e6567617469766506706f775f31300673796d626f6c08646563696d616c7308636f6e7461696e7306626f72726f77176765745f70726963655f6e6f5f6f6c6465725f7468616e09747970655f6e616d650a616464726573735f6f66036e65770d66726f6d5f627974655f76656304757466380675707365727414812adfd8ba2f589c0fe48c5170fa287cd36050dd487d17e2f4a765101f70ed00000000000000000000000000000000000000000000000000000000000000017e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b3870308700000000000000003086d0000000000000003086e0000000000000003081000000000000000052014812adfd8ba2f589c0fe48c5170fa287cd36050dd487d17e2f4a765101f70ed0a0221202b9ab1e972a281585084148ba1389800799bd4be63b957507db1349314e474450a020504414156450a022120bd640cddb72063e2ede34c6a0baf6699759b9837fcb06aa0e2fbcecb9b65fde70a02040341434d0a0221202a01deaec9e51a579277b34b122399984d0bbf57e2458a7e42fecd2829867a0d0a0204034144410a022120fa17ceaf30d19ba51112fdcc750cc83454776f47fb0112e4af07f15f4bb1ebc00a020504414c474f0a0221206d0af467543fc7daedf7abed96423877560c8d03725f3e5c87516774982a679c0a020403414e430a02212015add95022ae13563a11992e727c91bdb6b55bc183d9d747436c80a483d8c8640a0204034150450a02212003ae4db29ed4ae33d323568895aa00337e658e348b37509f5372ae51f0af00d50a0204034150540a022120b881c6dad5dd3dc9a83222f8032fb439859288119afc742d43adc305cef151cc0a0204034153520a022120681e0eb7acf9a2a3384927684d932560fb6f67c6beb21baa0f110e993b2653860a02060541544c41530a0221208ff1200345393bb25be4f4eeb2d97234e91f7e6213f3745a694b1436e700f2710a02040341544d0a022120b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e6128190a02050441544f4d0a0221204cbd623d7aa47003fff1cd75c3f96cb24a660014b697d91cfb7adcd204b952020a020504415553540a02212093da3352f9f1d105fdfe4971cfa80e9dd777bfc5d0f683ebb6e1294b92137bb70a020504415641580a022120b7e3904c08ddd9c0c10c6d207d390fd19e87eb6aab96304f571ed94caebdefa00a0204034158530a0221209d23a47f843f5c9284832ae6e76e4aa067dc6072a58f151d39a65a4cc792ef9f0a0204034241520a0221203dd2b63686a450ec7290df3a1e0b583c0481f651351edfa7636f39aed55cf8a30a0204034243480a0221207f981f906d7cfe93f618804f1de89e0199ead306edc022d3230b3e8305f391b00a020504424554480a0221202f95862b045670cd22bee3114c39763a4a08beeb663b145d283c31d7d1101c4f0a020403424e420a0221201ce9069708fb49e2f1b062fa4f1be0bb151475ca506939d6d8c14386d49f43dc0a02040342525a0a022120e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b430a0204034254430a022120097d687437374051c75160d648800f021086bc8edf469f11284491fda81923150a0204034254540a0221205bc91f13e412c07599167bae86f07543f076a638962b8d6017ec19dab4a828140a020504425553440a0221202dd14c7c38aa7066c7a508aac299ebcde5165b07d5d9f2d94dfbfe41f0bc5f2e0a0204034339380a0221202356af9529a1064d41e32d617e2ce1dca5733afa901daba9e2b68dee5d53ecf90a02050443414b450a02212015ecddd26d49e1a8f1de9376ebebc03916ede873447c1255d2d5891b92ce57170a02060543424554480a022120bd4dbcbfd90e6bc6c583e07ffcb5cb6d09a0c7b1221805211ace08c8378596270a0204034348520a022120e799f456b358a2534aa1b45141d454ac04b444ed23b1440b778549bb758f2b5c0a02040343485a0a0221209c479b12a2b2c1051715d4d462dd7a6abbb6dccabf3af31a53f6130a1cd88efc0a020504434954590a0221208517b35589b5f1f6ad626da2379ff592d5101b63aa661d75b7a883fdbda023f00a020504434f50450a0221204e53c6ef1f2f9952facdcf64551edb6d2a550985484ccce6a0477cae4c1bca3e0a020403434f570a0221208f218655050a1476b780185e89f19d2b1e1f49e9bd629efad6ac547a946bf6ab0a020504435553440a022120b0948a5e5313200c632b51bb5ca32f6de0d36e9950a942d19751e833f70dabfd0a0204034441490a022120dcef50dd0a4cd2dcc17e45df1676dcb336a11a61c69df7a0299b0150c672d25c0a020504444f47450a022120ca3eed9b267293f6595901c734c7525ce8ef49adafe8284606ceb307afa2ca5b0a020403444f540a022120ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0a0204034554480a022120c80657b7f6f3eac27218d09d5a4e54e47b25768d9f5e10ac15fe2cf9008814000a020504464944410a0221202fb245b9a84554a0f15aa123cbb5f64cd263b59e9a87d80148cbffab50c69f300a020504464c4f570a0221205c6c0d2386e3352356c3ab84434fafb5ea067ac2678a38a338c4a69ddc4bdb0c0a02040346544d0a0221206c75e52531ec5fd3ef253f6062956a8508a2f03fa0a209fb7fbc51efd9d35f880a0204034654540a022120301377b122716cee1a498e7930a1836c0b1db84667cc78bbbcbad6c330ea6afb0a02040347414c0a0221200781209c28fda797616212b7f94d77af3a01f3e94a5d421760aef020cf2bcb510a02050447414c410a022120baa284eaf23edf975b371ba2818772f93dbae72836bbdea28b07d40f3cf8b4850a020403474d540a0221206034b1f68b9363dff2cf9d53b1a88fb4d0929c65f34d532db53738853efc00ad0a020504474f46580a02212095609d32c98a467a72ac419f2e64bb2b8dbd5b00b74f3a0fd72f42343af1743d0a0205044858524f0a0221207a5bc1d2b56ad029048cd63964b3ad2776eadf812edc1a43a31406cb54bff5920a020403494e4a0a022120a4702f0f5818258783a1e47f453cb20b0fbec32ca67260e1d19dfcdd6a4d0ebb0a020605494e5445520a02212081a21b01c15b8d01f6cdfed65e00987cc4c901858c821b2089344987de3102e90a0204034a45540a022120ee42016c303126bd9263724e00f83a8114e84518c6e8ffc9738c001cc301daff0a0204034a53540a022120abe4f2b264560a397f38eec024369356e5c1ea4f7aab94729369f144b3d977790a0204034a55560a022120d1d95644ffc11ca502f21e067a7814144c56b37018515ced4335a886a827a3050a0206054c415a494f0a0221206e3f3fa8253588df9326580180233eb791e03b443a3ba7a1d892e73874e19a540a0204034c54430a022120e6ccd3f878cf338e6732bf59f60943e8ca2c28402fc4d9c258503b2edbe74a310a0205044c554e410a0221204456d442a152fd1f972b18459263ef467d3c29fb9d667e30c463b086691fbc790a0205044c554e430a0221205de33a9112c2b700b8d30b8a3402c103578ccfa2765696471cc672bd5cf6ac520a0206054d415449430a0221201888f463c27997174f97d2a36af29bf4648b61a5f69e67c45505a80f826bb7850a0205044d424f580a02212027d108eb764c912f49d3453a21dd95516619b1c45d0b607ee58a137ac8a6f32d0a0205044d45414e0a022120dfaeafde7f8ad3cb9ddbcc85ed7ae7e53910e7ab377fd75921920f97c80a8edc0a0204034d45520a0221200b46c1c04e9c914037cc4e0561a7e6787f6db0b89b7b65281f0f6fea1ce45a740a0204034d49520a0221205b70af49d639eefe11f20df47a0c0760123291bb5bc55053faf797d1ff9059830a0205044d4e474f0a022120c2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a40a0205044d534f4c0a022120c415de8d2eba7db216527dff4b60e8f3a5311c740dadb233e13e12547e2267500a0205044e4541520a02212005934526b94a9fbe4c4ce0c3792213032f086ee4bf58f2168a7085361af9bdc10a0203024f470a022120c572690504b42b57a3f7aed6bd4aae08cbeeebdadcf130646a692fe73ec1e0090a0204034f4e450a02212037505261e557e251290b8c8899453064e8d760ed5c65a779726f2490980da74c0a0205044f5243410a0221200afa3199e0899270a74ddcf5cc960d3c6c4414b4ca71024af1a62786dd24f52a0a020504504f52540a02212088e2d5cbd2474766abffb2a67a58755a2cc19beb3b309e1ded1e357253aa36230a020605504f52544f0a0221203d253019d38099c0fe918291bd08c9b887f4306a44d7d472c8031529141f275a0a0204035053470a022120fd0690232b0fae5efdc402c1b9aac74176383ff7daf87d021554bda24a38e0ec0a020504524143410a02212091568baa8beb53db23eb3fb7f22c6e8bd303d103919e19733f2bb642d3e7987a0a0204035241590a0221206ed3c7c4427ae2f91707495fc5a891b30795d93dbb3931782ddd77a5d8cb6db70a0204035342520a0221201021a42d623ab4fe0bf8c47fd21cc10636e39e07f91e9b2478551e137d512aaa0a02070653434e534f4c0a022120f8d030e4ef460b91ad23eabbbb27aec463e3c30ecc8d5c4b71e92f54a36ccdbd0a020504534c4e440a0221209fb0bd29fe51481b61df41e650346cc374b13c2bab2e3610364cd834a592025a0a020403534e590a022120ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d0a020403534f4c0a02212023245bb74254e65a98cc3ff4a37443d79f527e44e449750ad304538b006f21bc0a02040353524d0a022120a1a6465f4c2ebf244c31d80bc95c27345a3424e428c2def33eced9e90d3f701b0a0206055354534f4c0a0221204457960559b812558bb0f8cb7912f8bcb843eb801a3133ef45be998630ff8c050a020403544c4d0a022120433faaa801ecdb6618e3897177a118b273a8e18cc3ff545aadfc207d58d028f70a020504545553440a022120eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a0a020504555344430a0221202b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b0a020504555344540a022120ef94acc2fb09eb976c6eb3000bab898cab891d5b800702cd1dc88e61d7c3c5e60a020504555354430a0221207507a4629ad0143550666bce2e7cae0b961a0f624f821feaab642fe1be632f5c0a0204035641490a022120b216f7ca372b318985903866e0b6dc44a14564828c49f36d0d363805aa76335c0a02040357494e0a022120b82449fd728133488d2d41131cffe763f9c1693b73c544d9ef6aaa371060dd250a020403574f4f0a022120831624f51c7bd4499fe5e0f16dfa2fd22584ae4bdc496bbbbe9ba831b2d9bce90a0204035856530a02212026852e2d0696e25e6adaad2d7ca3a1f2f15aab68d317ace14d41b4128a7e780f0a0204035a42430a022120d6b3bc030a8bbb7dd9de46fb564c34bb7f860dead8985eb16a49cdc62f8ab3a50a02212073dc009953c83c944690037ea477df627657f45c14f16ad3a61089c5a3f9f4f20a02212008f781a893bc9340140c5f89c8a96f438bcfae4d1474cc0f688e3a52892c73180a0221204204a764d9e0ca8db0fd43b62728265bf82671ce8a8b4bfedba13672be12de620a022120cb1743d0e3e3eace7e84b8230dc082829813e3ab04e91b503c08e9a441c0ea8b0a02212044a93dddd8effa54ea51076c4e851b6cbbfd938e82eb90197de38fe8876bb66e0a022120c11efd88a9b2c96bc84bccd6ce4aa05bebad7aa760dbe5f2f00ef90c4abd50cc0a02212061226d39beea19d334f17c2febce27e12646d84675924ebb02b9cdaea68727e30a022120d7566a3ba7f7286ed54f4ae7e983f4420ae0b1e0f3892e11f9c4ab107bbad7b90a02212030029479598797290e3638a1712c29bde2367d0eca794f778b25b5a472f192de0a022120fc309467defa4b198c6b5bd59c08db4b9dfb27ddbcc32f31560f217b4ff8fc2b0a022120ecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a0a022120457064c555edae5b6b89267e992be4c58be5375f0e9ca9749391c7094f7d90330a022120f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b0a022120eb3b5720301b36fa074260e6e27e2cfff3a7c6bbb47564eb218a9a7f2a8c01930a02212006c532524fabd49cc142815502d785e4f34ec3bd035480efb770568d423f46c60a022120c098773aa18ebb7e84d5ee7ea7d97105ab2015a329f670012398cd2c8f5cc6ca0a0221200d10b9ccdc9af1d65cd4bafabf4e34db01c0ce83abba190230eaf26d7592cd210a022120970541e943e11d1bf1d4d763bc8e70995f613dc682f727045a866312312a63760a02212013ac8c71e4e1c61dece57bea76163d393bf75cd0db8e52981e1564fa592698cb0a022120b59d65c2e10af17c0d6f7d10be8d64c0c13dd15d957c4c39763b4cc55e5919370a02212087a67534df591d2dd5ec577ab3c75668a8e3d35e92e27bf29d9e2e52df8de4120a02212031775e1d6897129e8a84eeba975778fb50015b88039e9bc140bbd839694ac0ae0a02212036032e522b810babd8e3148e9f0d588af9e95e93b97ffb58566b837fdbd31f7f0a022120ca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a60a0221206660d7629213995af8aa169ad6a1cf1a725765d3741b7e7a27825f884a701b960a022120aa67a6594d0e1578faa3bba80bec5b31e461b945e4fbab59eeab38ece09335fb0a0221209b7bfd7654cbb80099d5edc0a29159afc9e9b4636c811cf8c3b95bd11dd8e3dd0a0221200184a60a47ab7c23fcb828d727b05748ef52433fb5ae96f775cc98c9049d8c2c0a0221206354d685c247f1efc36f967617beffa2ebd5a95d8ffe17de4498505c923067b80a02212021adabf73ad61903c1872fa220f84d3b1b9990cec2047f8317e2a67efcd1764e0a022120c999fe8a75bf9528931deb832e2934dd1ac138757d7f2c1398675b6f521d556f0a02212087fd5a8d0bf026239f98b53311d2cec2ee171e853f545e1ad742e092a97ef8600a02212051ae9b785e6aeb288955720faef15f63ee3ae21af38114ade8b3fc3d3831b5ad0a0221202d9315a88f3019f8efa88dfe9c0f0843712da0bac814461e27733f6b83eb51b30a0221202245aec1db780b8dc9f710173256996164f0a65f25a975453e4202a54371d2ea0a022120077e345652cb98edba89815a63a0ede724eba12d7a10c8498e0e762d581aca6b0a022120997e0bf451cb36b4aea096e6b5c254d700922211dd933d9d17c467f0d6f343210a022120677dbbf4f68b5cb996a40dfae338b87d5efb2e12a9b2686d1ca16d69b3d7f2040a0221206de025a4cf28124f8ea6cb8085f860096dbc36d9c40002e221fc449337e065b20a022120d2c2c1f2bba8e0964f9589e060c2ee97f5e19057267ac3284caef3bd50bd2cb50a02212070bf2974182b6ebf4eac64977170074315e7a07d7b58a963758060924ee9a1920a0221209f2acb902ee5c3a8e41c643164a498ed3089c99df3477189babd3682801340750a02212052800482aa2666c0d2621f8f0a8c19ee6e5e5039a65524e268315501b3355fbb0a0221202f317bea04ce89adb8acc85a1a68d20d6e89976d5e86306570a0bb3107e4916a0a022120b5366e5ded52c3db5d81635a624a39d81eb8c639427fc79c539e5c91e17c84940a0221207f57ca775216655022daa88e41c380529211cde01a1517735dbcf30e4a02bdaa0a02212027e867f0f4f61076456d1a73b14c7edc1cf5cef4f4d6193a33424288f11bd0f40a0221209b245faf19d2f3306b58821ef60b194d7b67eb5250635059d8eaae4a36337b280a02212085dafbfa99c733fdd33649551666958ca8f82fd0d849746e093b770caab249d20a0221206b86b78584e182c61729267d73593f48b6a929f3218234769281513cbe5e87ee0a0204035041490a0221201e761bb4e6b1e4d7899b618d389516ddbdfbdb858018b71c45cb6ade57c96f620a0221207730809b4a4656325b7fbc8157fd803c3da170727c541afc4db37773246258b10a022120cb9372930932694b8a74dd5599c0f9e236575f434faf05141d95803a91f044ed0a022120341d9502b1e6bc445036fd76f57bc824c09254a754289878b52a40eb067d2a0b0a022120f9917668f24038a383e51c0b019f5d9645d6785c6bf9a0d48483edf82ba5caec0a022120dd51a67a1b4d0702abf5b5385631b7d3e586993eadacf2e0d900c0a81edcffdd0a022120b5d2cee0b86bb0571db898ae7b9f288c5e272fa486d41a5bf375b52a0249d94c0a022120fe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd0a02212078ec25615d53d2486db101e829f77615c4408cbbd543088714b9f267da44591a0a022120b718e659619a031b41c6ea9122f146859a82d4a7edc17c55b1e5188e8b4c1d1c0a020504535445500a02212013f7925c9186b8cca50dde4bbf2d4fa9705052cceb6f2fc79df827e2b37d6f3b0a0221200adbf6463e27f60f171bcc498703a4282d1954ec3a85e1f6698b48ecde18c00e0a0221201bd1c59cd425aebf8a931c1b2a902b9a11e7d18dc68021e4a35a5cf24220a6c70a02212041f3625971ca2ed2263e78573fe5ce23e13d2558ed3f2e47ab0f84fb9e7ae7220a0221201fc18861232290221461220bd4e2acd1dcdfbc89c84092c93c18bdc7756c15880a022120026d1f1cf9f1c0ee92eb55696d3bd2393075b611c4f468ae5b967175edc4c25c0a022120eca4f9c5ce7cbef8a349fa9f6c12b23ac45b9ad91c4d1808c6a2dda841f95a020a022120834d3f05278b6f5c963670f437a2267c160914707328f888418902106bcd13d70a022120bf517e0f7ccfc307f0b2fa93b99a737641933989af6af769c928725989c21e660a0221206ff709bf1f0fdb46d991ae6839163df1e050d143429d737fc650b6b2143478080a02212064abe8a459058c60d55427f62be3dc4942c0ba93d1eb5cb85117b70b8e4651ad126170746f733a3a6d657461646174615f763063036d000000000000001a4552525f4e4f545f454e4f5547485f5045524d495353494f4e53006e00000000000000134552525f544f4b454e5f4e4f545f464f554e44007000000000000000174552525f414c52454144595f494e495449414c495a454400000202160b0302080408051a030102011b0b03020804030000000007440a0011080c020e0211090c080b00110a0c050600000000000000000c0a090c090b0a0b0907030911070c090c0a0e05110b0c070a07031a051e0e05110c0c0305210e0511090c030b030c060b0a0b090b060b0711070c090c0a0b0a0b090b01340911060c090c0a0b090335053c0b080b0a33110d1a0c0405420b080b0a33110d180c040b04020101000200010d26070429010304050638000238010c0338020c0007042b000c010a0110000a03380303160b01010702270a0110000b033804140c020b020b0110011411120c040e040b001100020200000101151438050c0007042b010c010a0110020a003806030e0b01010702270b0110020b0038071402030104010017a4060a00111407042103090b00010701270a00111429002003120b00010700273808063c0000000000000012000c6b0a000b6b2d000b0011142a000c6c070511160c020a6c0f00070611170b023809070711160c040a6c0f00070811170b043809070911160c060a6c0f00070a11170b063809070b11160c080a6c0f00070c11170b083809070d11160c0a0a6c0f00070e11170b0a3809070f11160c0c0a6c0f00071011170b0c3809071111160c0e0a6c0f00071211170b0e3809071311160c100a6c0f00071411170b103809071511160c120a6c0f00071611170b123809071711160c140a6c0f00071811170b143809071911160c160a6c0f00071a11170b163809071b11160c180a6c0f00071c11170b183809071d11160c1a0a6c0f00071e11170b1a3809071f11160c1c0a6c0f00072011170b1c3809072111160c1e0a6c0f00072211170b1e3809072311160c200a6c0f00072411170b203809072511160c220a6c0f00072611170b223809072711160c240a6c0f00072811170b243809072911160c260a6c0f00072a11170b263809072b11160c280a6c0f00072c11170b283809072d11160c2a0a6c0f00072e11170b2a3809072f11160c2c0a6c0f00073011170b2c3809073111160c2e0a6c0f00073211170b2e3809073311160c300a6c0f00073411170b303809073511160c320a6c0f00073611170b323809073711160c340a6c0f00073811170b343809073911160c360a6c0f00073a11170b363809073b11160c380a6c0f00073c11170b383809073d11160c3a0a6c0f00073e11170b3a3809073f11160c3c0a6c0f00074011170b3c3809074111160c3e0a6c0f00074211170b3e3809074311160c400a6c0f00074411170b403809074511160c420a6c0f00074611170b423809074711160c440a6c0f00074811170b443809074911160c460a6c0f00074a11170b463809074b11160c480a6c0f00074c11170b483809074d11160c4a0a6c0f00074e11170b4a3809074f11160c4c0a6c0f00075011170b4c3809075111160c4e0a6c0f00075211170b4e3809075311160c500a6c0f00075411170b503809075511160c520a6c0f00075611170b523809075711160c540a6c0f00075811170b543809075911160c560a6c0f00075a11170b563809075b11160c580a6c0f00075c11170b583809075d11160c5a0a6c0f00075e11170b5a3809075f11160c5c0a6c0f00076011170b5c3809076111160c5e0a6c0f00076211170b5e3809076311160c600a6c0f00076411170b603809076511160c620a6c0f00076611170b623809076711160c640a6c0f00076811170b643809076911160c660a6c0f00076a11170b663809076b11160c680a6c0f00076c11170b683809076d11160c6a0a6c0f00076e11170b6a3809076f11160c6e0a6c0f00077011170b6e3809077111160c700a6c0f00077211170b703809077311160c720a6c0f00077411170b723809077511160c740a6c0f00077611170b743809077711160c760a6c0f00077811170b763809077911160c780a6c0f00077a11170b783809077b11160c7a0a6c0f00077c11170b7a3809077d11160c7c0a6c0f00077e11170b7c3809077f11160c7e0a6c0f0007800111170b7e380907810111160c80010a6c0f0007820111170b8001380907830111160c82010a6c0f0007840111170b8201380907850111160c84010a6c0f0007860111170b8401380907870111160c86010a6c0f0007880111170b8601380907890111160c88010a6c0f00078a0111170b88013809078b0111160c8a010a6c0f00078c0111170b8a013809078d0111160c8c010a6c0f00078e0111170b8c013809078f0111160c8e010a6c0f0007900111170b8e01380907910111160c90010a6c0f0007920111170b9001380907930111160c92010a6c0f0007940111170b9201380907950111160c94010a6c0f0007960111170b9401380907970111160c96010a6c0f0007980111170b9601380907990111160c98010a6c0f00079a0111170b98013809079b0111160c9a010a6c0f00079c0111170b9a013809079d0111160c9c010a6c0f00079e0111170b9c013809079f0111160c9e010a6c0f0007a00111170b9e01380907a10111160ca0010a6c0f0007a20111170ba001380907a30111160ca2010a6c0f0007a40111170ba201380907a50111160ca4010a6c0f0007a60111170ba401380907a70111160ca6010a6c0f0007a80111170ba601380907a90111160ca8010a6c0f0007aa0111170ba801380907ab0111160caa010a6c0f0007ac0111170baa01380907ad0111160cac010a6c0f0007ae0111170bac01380907af0111160cae010b6c0f0007b00111170bae0138090204010401001da7050a0011140c010a01070421030b0b00010701270a00111429002003140b0001070027380806504600000000000012000c020b000b022d000b012a000c0307b10111160c4c0a030f00070611170b4c380907b20111160c6d0a030f00070a11170b6d380907b30111160c780a030f00070c11170b78380907b40111160c83010a030f00070e11170b8301380907b50111160c8e010a030f00071011170b8e01380907b60111160c520a030f00071211170b52380907b70111160c5d0a030f00071611170b5d380907b80111160c650a030f00071a11170b65380907b90111160c660a030f00071e11170b66380907ba0111160c670a030f00072411170b67380907bb0111160c680a030f00072611170b68380907bc0111160c690a030f00072811170b69380907bd0111160c6a0a030f00072a11170b6a380907be0111160c6b0a030f00072c11170b6b380907bf0111160c6c0a030f00072e11170b6c380907c00111160c6e0a030f00073011170b6e380907c10111160c6f0a030f00073211170b6f380907c20111160c700a030f00073811170b70380907c30111160c710a030f00073e11170b71380907c40111160c720a030f00074011170b72380907c50111160c730a030f00074211170b73380907c60111160c740a030f00074411170b74380907c70111160c750a030f00074611170b75380907c80111160c760a030f00074811170b76380907c90111160c770a030f00074a11170b77380907ca0111160c790a030f00074c11170b79380907cb0111160c7a0a030f00074e11170b7a380907cc0111160c7b0a030f00075011170b7b380907cd0111160c7c0a030f00075211170b7c380907ce0111160c7d0a030f00075411170b7d380907cf0111160c7e0a030f00075611170b7e380907d00111160c7f0a030f00075811170b7f380907d10111160c80010a030f00075a11170b8001380907d20111160c81010a030f00075c11170b8101380907d30111160c82010a030f00075e11170b8201380907d40111160c84010a030f00076211170b8401380907d50111160c85010a030f00076411170b8501380907d60111160c86010a030f00076a11170b8601380907d70111160c87010a030f00076c11170b8701380907d80111160c88010a030f00076e11170b8801380907d90111160c89010a030f00077011170b8901380907da0111160c8a010a030f00077211170b8a01380907db0111160c8b010a030f00077411170b8b01380907dc0111160c8c010a030f00077611170b8c01380907dd0111160c8d010a030f00077811170b8d01380907de0111160c8f010a030f00077a11170b8f01380907df0111160c90010a030f00077c11170b9001380907e00111160c91010a030f00077e11170b9101380907e10111160c92010a030f0007820111170b9201380907e20111160c93010a030f0007840111170b9301380907e30111160c4d0a030f0007e40111170b4d380907e50111160c4e0a030f0007860111170b4e380907e60111160c4f0a030f00078c0111170b4f380907e70111160c500a030f00078e0111170b50380907e80111160c510a030f0007900111170b51380907e90111160c530a030f0007920111170b53380907ea0111160c540a030f0007940111170b54380907eb0111160c550a030f0007960111170b55380907ec0111160c560a030f0007980111170b56380907ed0111160c570a030f00079a0111170b57380907ee0111160c580a030f0007ef0111170b58380907f00111160c590a030f00079c0111170b59380907f10111160c5a0a030f00079e0111170b5a380907f20111160c5b0a030f0007a00111170b5b380907f30111160c5c0a030f0007a20111170b5c380907f40111160c5e0a030f0007a40111170b5e380907f50111160c5f0a030f0007a60111170b5f380907f60111160c600a030f0007a80111170b60380907f70111160c610a030f0007aa0111170b61380907f80111160c620a030f0007ac0111170b62380907f90111160c630a030f0007ae0111170b63380907fa0111160c640b030f0007b00111170b6438090205010401001e120a00111407042103090b00010701270b0011142a000c020b010b020f011502060000001f5d0a010a031f0305051c0a020a0026030a05110b020b0017090c070c0405170b000b0217080c070c040b040b070c060c05055a0a01031f05230a03200c080525090c080b080328052f0b000b0216080c0e0c0d05560b01200b031f0335053c0b000b0216090c0c0c0b05520a000a0226034105480b000b0217090c0a0c09054e0b020b0017080c0a0c090b090b0a0c0c0c0b0b0b0b0c0c0e0c0d0b0d0b0e0c060c050b050b060207000000205e0a010a031f03050508080c0705140a0120030c05100a03200c040512090c040b040c070b070317051e0b000b02160b010c060c05055b0b01032105250b03200c080527090c080b08032a05410a000a0224032f05360b000b0217080c0a0c09053c0b020b0017090c0a0c090b090b0a0c0e0c0d05570a020a00240346054d0b020b0017080c0c0c0b05530b000b0217090c0c0c0b0b0b0b0c0c0e0c0d0b0d0b0e0c060c050b050b060200000001010000"; + let res = run_binary_test("sample_price_oracle", code); + assert!(res.is_ok(), "{:?}", res) +} + +#[test] +fn sample_aptosd_swap() { + let code = "a11ceb0b050000000c0100160216300346ee0104b4022205d602960407ec06de0708ca0e40068a0f8b01109510f9010a8e12520ce012e80e0dc821160000010101020103010401050106010700080009000a000b0700000c0700000d0800000e0700000f07000a28040207000400042b0401060102380800083a0000063c070100000010000100001102010000120101000013030100001401010000150101000016020100001701040000180506000019010700001a020100001b020100001c010100001d000100001e020100001f02010000200001000021000100092f01090009300105000a310b0c02070604320e01010607330205000934010f0009350104000936010f000a37110f020704033900010100033b02010100093d0104000a3e1617020704063f180f01000640191a01000a411b1c02070409421d010005431f040005441f0400094501200009460104000947010f0009480901000a490125020704014a022601060a4b1128020704140a150d1a0a1b121c1315141e0a1f052005210a151e290a2a0d2a142a1e2b0a1b1303060c05030001060c02060c0301030105050303030303010a050c03030303030505070b0502050803070b0502050803070802070803070b0601080401020205080303070b050209000901090009010107090101080402070b060109000900010108070b05020508030501070b06010800030107080207080302060b05020900090109000108070108080108002d0b0901050b0901050b0901050c0b0901050b0901050b0901050b0901050b090105030303030303070b06010801070b06010801070b06010801070b0601080103070803070803070803070803070b0502050803070b0502050803070b0502050803070b0502050803070b090105070b090105070b090105070b09010503030b0901050b0901050b0901050b090105070802070802070802070802070802030301060b050209000901010b0901090001060b0901090001070b0901090001090002070b0502090009010900030709010b090109000b09010900020503010801020303010c04010103030a03030303030505070b0502050803070b0502050803070803070b0901050b090105070803070b0502050803070b0901050b0901050a050a0b0502050803060c030c0b060108040c0b060108000c0b060108010c010b050209000901010b060109000c0b0901050c070b0502050803050b090105070b06010801060803070b0502050803070b0901050b090105070802060c030609010b090109000b090109000d6170746f737061645f73776170076163636f756e740a6170746f735f636f696e04636f696e056576656e74066d6174683634066f7074696f6e067369676e65720d6170746f737061645f636f696e06636f6e6669670e6974657261626c655f7461626c65104269644170746f735061644576656e7417446973747269627574654170746f737061644576656e74114c61756e636850616452656769737472790f546f6b656e446973747269627574650e57686974654c6973744576656e740c61646457686974654c6973740c6173736572745f61646d696e136173736572745f6e6f5f656d657267656e63790b6269644170746f735061640d64697374726962757465416c6c0e64697374726962757465417470701064697374726962757465536561736f6e0f67657453776170546f74616c4269640c67657457686974654c6973740d67657457686974654c697374730a696e697469616c697a650f6c61756e6368506164536561736f6e09726566756e64416c6c0b726566756e644170746f730b7265736574536561736f6e0f77686974654c697374536561736f6e0d77697468647261774170746f731077697468647261774170746f73506164036361700362696408696e766573746f72106469737472696275746564546f6b656e06726566756e6409696e766573746f72730d4974657261626c655461626c6508746f74616c426964126269646170746f737061645f6576656e74730b4576656e7448616e646c6519646973747269627574656170746f737061645f6576656e74731077686974656c6973745f6576656e74730b64697374726962757465640c676574537761705374617465126765745265736f757263654164647265737317626f72726f775f6d75745f776974685f64656661756c740a656d69745f6576656e740a616464726573735f6f660b6973456d657267656e63791467657453776170436f6e6669674861726443617011697342797061737357686974654c69737408636f6e7461696e73094170746f73436f696e087472616e736665720c4170746f73506164436f696e087265676973746572064f7074696f6e1a67657453776170436f6e666967417074546f417074745261746508686561645f6b65790769735f736f6d6507657874726163740f626f72726f775f697465725f6d75740a6d696e7441747070546f036d696e036d6178116765745265736f757263655369676e65721467657453776170436f6e666967536f66744361701967657453776170436f6e666967456e61626c65526566756e640c736574537761705374617465036e6577106e65775f6576656e745f68616e646c650b626f72726f775f6974657241376d8231e6aedc29a19459e804b3770a250c3f367ac8d0f91e10842e8c906d0000000000000000000000000000000000000000000000000000000000000001030800e87648170000000308950100000000000003089a0100000000000003089b010000000000000308930100000000000003089801000000000000030896010000000000000308970100000000000003089901000000000000020104020105020101020103020102052041376d8231e6aedc29a19459e804b3770a250c3f367ac8d0f91e10842e8c906d126170746f733a3a6d657461646174615f7630e4010893010000000000000f4552525f5045524d495353494f4e530095010000000000000d4552525f454d455247454e4359009601000000000000104552525f534541534f4e5f454e444544009701000000000000144552525f534541534f4e5f4e4f545f5245534554009801000000000000114552525f534541534f4e5f414354495645009901000000000000104552525f534541534f4e5f5354415445009a01000000000000134552525f484152444341505f52454143484544009b01000000000000144552525f4e4f545f494e5f57484954454c4953540b6572726f7220636f64657300020322032303240501020522032303250326032405020205270b050205080329032a0b060108002c0b060108012d0b06010804030206220323032e03250326032405040206220323032e032503260324050001000102083c0b0011011112070d21030807082711132a020c0c0a0c0f000c0b0b0c0f010c0e0b0b0c0a0a010c090b010c080b0a0b090600000000000000000600000000000000000600000000000000000600000000000000000600000000000000000b08120338000c0d0b020a0d0f02150b0e0a0d1002140a0d1003140a0d1004140a0d1005140a0d1005140b0d10061412043801020100000001080b001116070e210307070427020200000001061117200305070127020301000102106111021112070c2103090b000107082711180c0611132a020c0811190c040a080f000a0011160c030c020b022e0b0338020c070b040b071e03250b00010b08010703270a081007140b062503310b00010b08010702270a081007140a01160a080f07150a080f080c050a0011130a0138030a0038040b080f000a00111607000600000000000000000600000000000000000600000000000000000600000000000000000b001116120338000c090b010a090f03150b050a091002140a091003140b091006141200380502040000010215a00311180c13111d0c2b11132a020c260b261007140c2c0b2c0a13250310055c11132a020c270a270f000c180b270f090c0f0a182e38060c010d010c1c0a1c2e3807032405550a180b1c380838090c22010c140a141003140a140f0a150a14100a140a2b180a140f04150a141006140a1410041411220a0f0a141002140a141003140a141004140a141005140b141006141201380a0d220c1c051f0b1c010b18010b0f01059f030b130c0a11132a020c2a0a2a0f000c1b0b2a0f090c120a1b2e38060c040d040c1f0a1f2e3807037205c3010a1b0b1f380838090c23010c170a171002140c0d0a171003140c0b0b0d0b0b11230a0a11230c090a0906000000000000000024038c0105b4010a090a170f0a150a090a2b180a170f04150b0a0b09170c0a0a171006140a1710041411220a120a171002140a171003140a171004140a171005140b171006141201380a05b6010b17010a0a0600000000000000002503bb0105c0010b1b010b120105c3010d230c1f056d0a0a0600000000000000002403c80105b30211132a020c280a280f000c190b280f090c100a192e38060c000d000c1d0a1d2e380703dc0105b3020a190b1d380838090c24010c150a151003140a15100a141706000000000000000011240a0a11230c200a200600000000000000002403f40105a4020a15100a140a20160a150f0a150a200a2b180c210a151004140a21160a150f04150b0a0b20170c0a0a151006140b2111220a100a151002140a151003140a151004140a151005140b151006141201380a05a6020b15010a0a0600000000000000002503ab0205b0020b19010b100105b3020d240c1d05d7010b0a0600000000000000002503b90206a1860100000000002711132a020c290a290f000c1a0b290f090c110a1a2e38060c020d020c1e0a1e2e380703cd020599030a1a0b1e380838090c25010c160a161003140c0c0a16100a140c0e0a0c0a0e2603e8020b1a010b16010b1101061127000000000000270b0c0b0e1706000000000000000011240a160f05150a161005140600000000000000002403f70205940311250c030e030a161006140a16100514110d0a110a161002140a161003140a161004140a161005140b161006141201380a0596030b16010d250c1e05c8020b1e010b1a010b1101020500000102211a11260c0211132a021007140c0311270c010b01030c05110b030b02230c000513090c000b0003160518110c05191104020601000102010f0b00110111021112070c210309070827070911281105070a1128020701000102010511132b02100714020801000102222511132a020f000c090b090c080a000c070b000c060b080b070600000000000000000600000000000000000600000000000000000600000000000000000600000000000000000b06120338000c0a0a0a1002140a0a1003140a0a100a140a0a1004140b0a100514020901000102232611132a020f000c03400500000000000000000c060a032e38060c000d000c040a042e3807031105200a030b04380838090c05010c020d060b0210061444050d050c04050c0b04010b03010b06020a01000024220b00110111250c0a0e0a0c02380b0c0111250c040e04380c0c0511250c060e06380d0c0711250c080e08380e0c090b020b010600000000000000000b070b090b0512022d02070b1128020b010000010b0b0011011112070d210308070827070c1128020c00000102274a11132a020c0a0a0a0f000c070b0a0f090c050a072e38060c000d000c0811250c010e010c0b0a082e3807031805410a070b0838080c030c020b022e0b03380f0c09010c060a0b0a061006140a06100314110d0a050a061002140a061003140a061004140a061005140b061006141201380a0d090c0805130b0b010b08010b07010b0501020d00000001050b000b010b023803020e010000010b0b0011011112070a210308070627070b1128020f010000010b0b0011011112070b210308070727070d1128021001000020090b00110111250c030e030b010b023803021101000020090b00110111250c030e030b010b02381002020002040300030103030304030502010202020303020000"; + let res = run_binary_test("sample_aptosd_swap", code); + assert!(res.is_ok(), "{:?}", res) +} + +#[test] +fn sample_router() { + let code = "a11ceb0b050000000a01000e020e0603148f0104a3012805cb018f0207da03f90208d30640069307a00110b3082b0cde08db110000010101020003000400050006010a0401000100070000000008010202000000090102020000020b050600050c060700050d050200030e0207020000040f02070200000410020a0200000111020c01000612000d000113020f01000414020a0200000115100f0100031611120200000117130201000418020d0200000519140d00041a1500020000041b020a020000041c020d020000051d140d00031e111202000006080609070907080808090b0b0e0c080d0b0e080f0b100812080f0e0809090e130914091209160802040403060c030300030404043501010101010103030404040404040404040b000109000b000109000b000109000b000109000b000109000b000109000b000109010b000109010b0001090103030303030303030404030301010404010404040503030303030301060c0105010102090009010209010900010301090001020104010901010b0001090002060c0308060c070b00010900070b00010901030301030302030302050b000109000305040106060c010303030432010103030404040404040404040b000109000b000109000b000109000b000109000b000109000b000109000b000109010b000109010b000109010303030303030404030301010404010404040505030303030303030306726f7574657204636f696e067369676e657203616d6d0b636c6f625f6d61726b657403666565047574696c0873696d706c69667918737761705f636f696e5f666f725f65786163745f636f696e18737761705f65786163745f636f696e5f666f725f636f696e04436f696e0a616464726573735f6f660a6665655f65786973747316696e697469616c697a655f6665655f64656661756c740b706f6f6c5f6578697374730d6d61726b65745f657869737473086c6f745f73697a6508646563696d616c7303657870047a65726f0c6e5f6269645f6c6576656c730877697468647261771d636f696e5f737761705f636f696e5f666f725f65786163745f636f696e076465706f7369740b626573745f6269645f61750c73756274726163745f66656516706c6163655f6f726465725f666f725f726f757465720c6e5f61736b5f6c6576656c730b626573745f61736b5f6175076164645f6665651d636f696e5f737761705f65786163745f636f696e5f666f725f636f696e49661cd59c0b89440313af587bc99c3d38614d9a52479eb3f7c7c766d580c30b00000000000000000000000000000000000000000000000000000000000000010308c9000000000000000308ca000000000000000308c800000000000000030804000000000000000308070000000000000003086500000000000000030866000000000000000308030000000000000003080200000000000000030864000000000000000308ffffffffffffffff0308050000000000000003080100000000000000030868000000000000000308670000000000000003080600000000000000126170746f733a3a6d657461646174615f7630170104000000000000000c45544553545f4641494c4544000001000003190a000c030a010c040a01320000000000000000000000000000000022030905120b000a01190c020b010c000b020c0105040b030a001a0b040b001a020101040004ec030a0011030c310a311104200308050a0a0011053800030d0510080c03051238010c030b030c2d38020c2a38030c290a2d0b291f031d05fb0138040c27320a000000000000000000000000000000380535110a0c0e0600000000000000000c320600000000000000000c3438060c1a0a340a0223032f05340a320a01230c060536090c060b06033905eb01380706000000000000000021033e055f0a000a010a321738080c140b000d140d1a0a010a32170a020a34170906000000000000000006000000000000000038090c210c1d0a310b14380a0b320b21160c320b340b1d160c3405eb01380b0c130a310a130811110c120a020a3417350a0e180a121a340c090b090a272303750596010a000a010a321738080c180b000d180d1a0a010a32170a020a34170906000000000000000006000000000000000038090c230c1f0a310b18380a0b320b23160c320b340b1f160c3405eb010a0e0a1211000c250c2b0a000a010a321738080c190a000d190d1a0a010a32170a020a3417080b2b340b253438090c240c200a310b19380a0b320b24160c320b340b20160c340a340a022303c20105c7010a320a01230c0805c901090c080b0803cc0105ea010a020a3417350a0e180b121a340c0a0a000907060b13340b0a3200000000000000000000000000000000380c0c2e0c0d0b320b0d34160c320b340b2e34160c34052a0b320b012503f1010707270b340b022103f7010708270b310b1a380d05eb030a2d0a2a1f03800205b203380e0c28320a000000000000000000000000000000380f35110a0c0f0600000000000000000c330600000000000000000c3538060c1b0a350a02230392020597020a330a01230c04059902090c040b04039c0205a20338100600000000000000002103a10205a402080c0505aa020a020a35170a28230c050b0503ad0205ce020a000a010a331738080c150b000d150d1b0a010a33170a020a35170906000000000000000006000000000000000038090c220c1e0a310b15380a0b330b22160c330b350b1e160c3505a20338110c110a310a110811150c100b100a0f11000c260c2c0a000a010a331738080c160a000d160d1b0a010a33170a020a3517080b2c340b263438090c360c370a310b16380a0b330b36160c330b350b37160c350a350a02230381030586030a330a01230c07058803090c070b07038b0305a1030a000807060b11340a020a3517320000000000000000000000000000000038120c2f0c0b0b330b2f34160c330b350b0b34160c35058d020b330b012503a8030707270b350b022103ae030708270b310b1b380d05eb030b2d03b50305cd030a000a0138080c1738060c1c0b000d170d1c0b010b0209060000000000000000060000000000000000380901010a310b17380a0b310b1c380d05eb030b2a03d00305e7030b00080705070a0a02320000000000000000000000000000000038120c300c0c0b0c340b022103e0030707270b30340b012503eb030708270b0001070c27020201040016d1030a0011030c2b0a2b1104200308050a0a0011053800030d0510080c03051238010c030b030c2738020c2438030c230a270a231f031d05b70138040c21320a000000000000000000000000000000380535110a0c0a0600000000000000000c2d0600000000000000000c2f38060c160a2d0a0123032f05a70138070600000000000000002103340537080c04053d0a010a2d170a21230c040b040340055f0a000a010a2d1738080c100b000d100d160a010a2d170600000000000000000906000000000000000006000000000000000038130c1c0c190a2b0b10380a0b2d0b1c160c2d0b2f0b19160c2f05a701380b0c0f0a2b0a0f0811110c0e0b0e0a0a11000c1f0c250a000a010a2d1738080c140a000d140d160a010a2d17060000000000000000080b25340b1f3438130c310c330a2b0b14380a0b2d0b31160c2d0b2f0b33160c2f0a2d0a012303900105a6010a000907060b0f340a010a2d173200000000000000000000000000000000380c0c280c080b2d0b0834160c2d0b2f0b2834160c2f052a0b2d0b012103ad010707270b2f0b022603b3010708270b2b0b16380d05d0030a270b241f03bc01059403380e0c22320a000000000000000000000000000000380f35110a0c0b0600000000000000000c2e0600000000000000000c3038060c180a2e0a012303ce0105840338100600000000000000002103d30105f2010a000a010a2e1738080c150b000d150d180a010a2e170600000000000000000906000000000000000006000000000000000038130c1d0c1a0a2b0b15380a0b2e0b1d160c2e0b300b1a160c3005840338110c0d0a2b0a0d0811150c0c0a010a2e17350a0b180a0c1a340c050b050a222303880205a7020a000a010a2e1738080c110b000d110d180a010a2e170600000000000000000906000000000000000006000000000000000038130c1e0c1b0a2b0b11380a0b2e0b1e160c2e0b300b1b160c300584030a0b0a0c11000c200c260a000a010a2e1738080c120a000d120d180a010a2e17060000000000000000080b26340b203438130c320c340a2b0b12380a0b2e0b32160c2e0b300b34160c300a2e0a012303d1020583030a010a2e17350a0b180b0c1a340c060a000807060b0d340a06320000000000000000000000000000000038120c2a0c070a07340b062503ee020b0001061111000000000000270a2a340a010a2e172503f9020b0001062222000000000000270b2e0b2a34160c2e0b300b0734160c3005c9010b2e0b0121038a030707270b300b02260390030708270b2b0b18380d05d0030b2703970305b2030a000a0138080c1338060c170a000d130d170b010b0209060000000000000000060000000000000000381301010b0011030c2c0a2c0b17380d0b2c0b13380a05d0030b2303b50305cc030b000907050600000000000000000a013200000000000000000000000000000000380c0c290c090b09340b012103c5030707270b29340b022603d0030708270b0001070c270200"; + let res = run_binary_test("sample_router", code); + assert!(res.is_ok(), "{:?}", res) +} + +#[test] +fn sample_pool() { + let code = "a11ceb0b050000000c010020022079039901c90204e2036605c804fd0507c50aa80c08ed166006cd17c101108e19bb020ac91bd4020c9d1eb3250dd043340000010101020103010401050106010701080109010a020b000c000d000e000f0010070000110600001206000013060000140600001508000000040000160800001708000018060000190600001a0600001b0600071d07000b2707000b3a0700053c040106010344040100010245080009470402030100010b480400084e0402030100010b6c07000e7807000e7b07000e7e07000e80010700001c000100001e020100001f030100002002010000210201000022020100002300010000240201000025040100002605010000280607000029080100002a090100002b0a0100002c0b01000658050d0008590f07020300045a101000085b1213020300045c101000035d15160100035e17010100035f1810010005601a0101060b611e1c000b621f06000b632010000b64212200096524010203000a66250101000867122a0203000a682c2d01000a672e2f01000967312a0203000b69320100096a3301020300036b340101000d6d393a000c6d393a0009593b070203000b6e1c3c000b6f3d10000b703d10000b713d0d0003723e16010007733f1d000d74393a000c74393a000975013302030408654401020300087501460203040176054701060b7706100008790f490203000e7a4b4a000e7c4c4d000f7d4e0101040e7f3951000e81010e5300100e1011121114141514161417191c231d1c17261728120e1e111f2b202b12302123232324141735173617371f1c201c27232c1417403023103031303111310e17453211320e32303345333733263319333533363328334035303511384d384a3851350e385303060c04030006060c040a050a080d0a080d0a0306060c04020303030b060c020a050a080d0a080d0a03030303030201060c01080e010103060c05080d02060c0407060c03030303030302060c05040b11010812070805070806070808010502050a0402060b150209000901090001030204080602070b15020900090109000107090101081202060c03010b1101090002070b110109000b1101090001060b1101090001080202070b100109000900070708050303070806070808080f0a080f01080f01080d0405080d080d030305080d080d0205080f03060c080f0301081402080f081403070b1302090009010900090102070a09000a0900010803030708050708060708080108041a06040604030b1101081205080d070a0405020307080503030303030307080803080f0a080f0b1302080f0814040302070a04010901010402060a090006090002010302070a0900030109000208000a0402070b130209000901090002060c0814010b13020900090102050b1101090001080c01080b0108092c03030303030816050405080d040302030a080f0303030503080d03070b1001080a020b11010812030307080503030303030303070806070b150204080603060816030503080f0a080f0503030303030602030303030302060b13020900090109000108160106081602070b1101090003010a0201080a2b03030303030816050405080d040302030a080f0303030503080d03070b1001080a020b110108120307080503030303030303070806070b150204080603060816030503080f0a080f08070805030303070806070808080f0a080f0d01050b1101081206080d060507080507040303070808080f0a080f0b1302080f081403070b15020900090109000901010801010b150209000901010b10010900080800030403060a040608060708080a0817010609010108170d05030305080d020303020a080f0304030405080d0a040a081701081802060c09000206080607080817030303020303030303020303030303020303030303030301081902060a0407080801081a04506f6f6c076163636f756e740a6170746f735f636f696e04636f696e056572726f72056576656e74067369676e657206737472696e67057461626c65117461626c655f776974685f6c656e67746806766563746f7205746f6b656e104578706f6e656e7469616c43757276650b4c696e6561724375727665054d6f64656c04566965770c436f6c6c656374696f6e49640f437265617465506f6f6c4576656e74144465706f736974436f696e506f6f6c4576656e74154465706f736974546f6b656e506f6f6c4576656e740d45646974506f6f6c4576656e740a4576656e7453746f726508506f6f6c4775696405506f6f6c730f52656d6f7665506f6f6c4576656e7409537761704576656e74155769746864726177436f696e506f6f6c4576656e74165769746864726177546f6b656e506f6f6c4576656e740b4465706f736974436f696e06537472696e670c4465706f736974546f6b656e0845646974506f6f6c0a52656d6f7665506f6f6c1753776170436f696e466f7253706563696669634e4654730f537761704e465473466f72436f696e0c5769746864726177436f696e0d5769746864726177546f6b656e066372656174650b696e69745f6d6f64756c650b546f6b656e4461746149640a69735f6572633131353515766965775f636f6c6c656374696f6e5f706f6f6c7309766965775f706f6f6c0f766965775f70726963655f63616c630f766965775f757365725f706f6f6c7312636f6c6c656374696f6e5f63726561746f720f636f6c6c656374696f6e5f6e616d650763726561746f7207706f6f6c5f69640a73706f745f70726963650563757276650564656c7461116c705f6665655f6d756c7469706c69657204747970650673656e646572136465706f7369745f636f696e5f616d6f756e7405636f696e7309746f6b656e5f69647307546f6b656e49640b6372656174655f706f6f6c0b4576656e7448616e646c650b72656d6f76655f706f6f6c126465706f7369745f746f6b656e5f706f6f6c116465706f7369745f636f696e5f706f6f6c1377697468647261775f746f6b656e5f706f6f6c1277697468647261775f636f696e5f706f6f6c09656469745f706f6f6c047377617004436f696e094170746f73436f696e06746f6b656e730f5461626c65576974684c656e67746805546f6b656e0c7472616e73616374696f6e7317746f74616c5f7472616e73616374696f6e5f76616c75650f6c705f6665655f6561726e696e677305636f756e7405706f6f6c73055461626c650a757365725f706f6f6c7310636f6c6c656374696f6e5f706f6f6c730b636f696e5f616d6f756e740c70726f746f636f6c5f6665650e70726f746f636f6c5f70617965650b726f79616c74795f6665650d726f79616c74795f7061796565066c705f6665651477697468647261775f636f696e5f616d6f756e740a616464726573735f6f6608636f6e7461696e7310696e76616c69645f617267756d656e740a626f72726f775f6d7574117065726d697373696f6e5f64656e696564087769746864726177056d657267650576616c75650a656d69745f6576656e74136372656174655f746f6b656e5f69645f726177146372656174655f746f6b656e5f646174615f69640a62616c616e63655f6f660e77697468647261775f746f6b656e0361646406617070656e640672656d6f766508696e6465785f6f660d6465706f7369745f746f6b656e0d64657374726f795f656d707479076465706f73697407526f79616c74790a676574427579496e666f0b6765745f726f79616c7479176765745f726f79616c74795f64656e6f6d696e61746f72156765745f726f79616c74795f6e756d657261746f72116765745f726f79616c74795f7061796565076578747261637404757466380b67657453656c6c496e666f036e6577106e65775f6576656e745f68616e646c65156765745f746f6b656e646174615f6d6178696d756d08506f6f6c5669657706626f72726f7709706f6f6c5f7669657713436f6c6c656374696f6e506f6f6c735669657715636f6c6c656374696f6e5f706f6f6c735f7669657704766965770d507269636543616c63566965770f70726963655f63616c635f766965770d55736572506f6f6c73566965770f757365725f706f6f6c735f76696577ecb44cec6276ddc5860a13b976262c786e06af8f7306923cabec17808dabf0940000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303086600000000000000030869000000000000000308680000000000000003086e000000000000000308670000000000000003086a0000000000000003086b0000000000000003086c000000000000000308650000000000000003086d000000000000000520ecb44cec6276ddc5860a13b976262c786e06af8f7306923cabec17808dabf09403086400000000000000052000000000000000000000000000000000000000000000000000000000000000000a0204036275790a02050473656c6c126170746f733a3a6d657461646174615f7630a6020a6500000000000000074552525f4e554d006600000000000000134552525f444946465f434f4c4c454354494f4e006700000000000000124552525f4e4f545f45584953545f504f4f4c006800000000000000154552525f494e56414c49445f504f4f4c5f54595045006900000000000000154552525f494e56414c49445f504f4f4c5f41524753006a000000000000001c4552525f4e4f545f4558495453545f544f4b454e5f494e5f504f4f4c006b00000000000000124552525f4e4f545f484156455f544f4b454e006c00000000000000144552525f4e4f545f504f4f4c5f43524541544f52006d00000000000000184552525f504f4f4c5f4e4f545f454e4f5547485f434f494e006e00000000000000114552525f49535f313135355f544f4b454e000002022d052e080d0102092f0530042d052e080d3103320233033403350202020a360530042d052e080d37033803310332023303340303020a360530042d052e080d390a080f3803310332023303340304020730042d052e080d31033202330334030502083b0b100108013d0b100108093e0b100108033f0b10010802400b1001080c410b1001080b420b10010804430b1001080a06020e2f053103380b11010812460b1302080f08142d052e080d3202330334033502390a080f49034a044b030702014c040802034d0b15020408064f0b1502050a04500b150208000a0409020c2f0530042d052e080d3103320233033403350249034a044b030a0210360530042d052e080d310332023303390a080f510352035305540355055603380335080d0b020a360530042d052e080d5703380331033202330334030c020a360530042d052e080d390a080f380331033202330334030001000205080c61070a2a080c06070a2a050c040a0610000a00110f3800040d05160b00010b06010b040107041111270a0610010a013801041c05250b00010b06010b040107041111270b060f010a0138020c050a051002140a00110f210432053b0b00010b05010b040107071113270a000a0238030c030a050f030b0338040b040f040b00110f0b010a051005140a051006140b020a05100338050a051007140a051008140a051009140b05100a1412023806020101000205081bd801070a2a080c0a070a2a050c060a0a10000a00110f3800040d05160b00010b0a010b060107041111270a0a10010a013801041c05250b00010b0a010b060107041111270b0a0f010a0138020c09401c00000000000000000c0c0a091002140a00110f210434053d0b00010b09010b060107071113270e02410d0c080600000000000000000c070a070a082304b60105470e020a07420d0a09100521044f05580b00010b09010b060107001111270e030a07421d0a09100621046005690b00010b09010b060107001111270e020a07420d140e030a07421d140e040a07421d140e050a0742101411180c0b0e020a07420d140e030a07421d140e040a07421d141119110a20048c010595010b00010b09010b060107031111270d0c0a0b441c0a00110f0a0b111a0601000000000000002604a00105a9010b00010b09010b060107061111270a090f0b0a0b0a000b0b060100000000000000111b38070b07060100000000000000160c0705420a090f0c0a0c38080b060f0d0b00110f0b010a091005140a091006140b0c0a09100338050a091007140a091008140a091009140b09100a1412033809020201000205082759070a2a080c08070a2a050c060a0810000a00110f3800040d05160b00010b08010b060107041111270a0810010a013801041c05250b00010b08010b060107041111270b080f010a0138020c070a071002140b00110f21043205390b07010b060107071113270a020a070f08150a040a070f09150a030a070f07150a050a070f0a150b060f0e0b010a071005140b071006140b030b020b040b051204380a0203010002050829dc01070a2a080c17070a2a050c100a1710000a00110f3800040d05160b00010b17010b100107041111270a170f000a00110f380b0c1f0a1710010a0138010422052d0b1f010b00010b17010b100107041111270a170f010a01380c13060c150c1c0c1d010c1e0c160c0f0c0e0c0b0c0a0c1b0c090c180c0d0a0d0a00110f21044605510b1f010b00010b17010b100107071113270a1f0e010c062e0b06380d0c12010b1f0b12380e010b170f0f0a0a0a0b1200380f0c0c0a0c0e010c072e0b07380d0c13046d05760b00010b10010b0c0107051111270b0c0b13380e010600000000000000000c110e02410d0c14401c00000000000000000c1a0a110a142304a5010586010e020a11420d140e030a11421d140e040a11421d140e050a1142101411180c190d1a0a19441c0a000d1b0b19381011220b11060100000000000000160c110581010b1b38110e0938050c080a00110f0b0938120a100f100a0d0a010a0a0a0b0b1a0600000000000000000600000000000000003100060000000000000000060000000000000000120c38130a100f110b0d0a010a0a0a0b0b080600000000000000000600000000000000003100060000000000000000060000000000000000120b38140b100f120b00110f0b010b0a0b0b0b180b0e0b0f0b160b1e0b1d0b1c0b15120938150204010002050838d502070a2a080f010c2a070a2a050c210a2a0a010c102e0b103801040f05180b00010b2a010b210107041111270e02410d0c270b2a0a0138020c290a2910081431012104380a291007140a291009140a270a29100a14070b11250c0a0c090c080c070c060c1d055a0a29100814310221043f05480b00010b29010b210107021111270a291007140a291009140a270a29100a14070b11260c0a0c090c080c070c060c1d0b1d0b060b070b080b090b0a0c240c2b0c1f0c250c26310021046905720b00010b29010b21010701111127070c0600000000000000000600000000000000000c2f0c2d0c2e0b260a290f07150b250a290f0915401c00000000000000000c310a000a1f38030c1e0600000000000000000c220a220a272304f401058d010e020a22420d140e030a22421d140e040a22421d140e050a2242101411180c300a29100c0e3038160c2304a60105af010b00010b29010b210107051111270a290f0c0b233817010d310a30441c0a29100b0a30381804bd0105c6010b00010b29010b210107051111270a000a290f0b0a30381011220b3011280c0b0e0b0c2c0a2c11290c200a2c112a0c280b2c112b0c2e0a200600000000000000002204ef010a1f0a271a0b28180b201a0c2d0b2f0a2d160c2f0a2e0d1e0a2d381938120b22060100000000000000160c220588010a291013140a1f35160a290f13150a29101414060100000000000000160a290f1415070a0d1e0a2b381938120a290f030b1e38040b210f150c1c0b00110f0c0c0b010c0d0a291005140c0e0a291006140c0f0a291007140c110a291008140c120a291009140c130b310c140b1f0a2b160b2d160c150b2b0c160b2f0c170b2e0c180b240c19070d112d0c1a0b29100338050c1b0b1c0b0c0b0d0b0e0b0f0b110b120b130b140b150b16070a0b170b180b190b1b0b1a120a381a02050100020508418c03070a2a080f010c29070a2a050c200a290a010c102e0b103801040f05180b00010b29010b200107041111270e02410d0c250b290a0138020c280a2810081431012104380a281007140a281009140a250a28100a14070b112e0c0a0c090c080c070c060c1d055a0a28100814310221043f05480b00010b28010b200107021111270a281007140a281009140a250a28100a14070b112f0c0a0c090c080c070c060c1d0b1d0b060b070b080b090b0a0c220c2a0c270c230c24310021046905720b00010b28010b20010701111127070c0600000000000000000600000000000000000c2e0c2c0c2d401c00000000000000000c300a280f030a270a2a1738190c1e0600000000000000000c210a210a2523049a020588010e020a21420d0a281005210490010599010b00010b28010b200107001111270e030a21421d0a2810062104a10105aa010b00010b28010b200107001111270e020a21420d140e030a21421d140e040a21421d140e050a2142101411180c2f0e020a21420d140e030a21421d140e040a21421d141119110a2004cd0105d6010b00010b28010b200107031111270d300a2f441c0a00110f0a2f111a0601000000000000002604e10105ea010b00010b28010b200107061111270a280f0b0a2f0a000a2f060100000000000000111b38070b2f11280c0b0e0b0c2b0a2b11290c1f0a2b112a0c260b2b112b0c2d0a1f060000000000000000220495020a270a251a0b26180b1f1a0c2c0b2e0a2c160c2e0a2d0d1e0a2c381938120b21060100000000000000160c210583010a280f0c0a303808070a0a280f030a2a381938120b240a280f07150b230a280f09150a00110f0b1e38120a281013140a270a2a170b2e1735160a280f13150a28101414060100000000000000160a280f14150b200f150c1c0b00110f0c0c0b010c0d0a281005140c0e0a281006140c0f0a281007140c110a281008140c120a281009140c130b300c140b270a2a170a2c170c150b2a0c160b2c0c170b2d0c180b220c19070e112d0c1a0b28100338050c1b0b1c0b0c0b0d0b0e0b0f0b110b120b130b140b150b16070a0b170b180b190b1b0b1a120a381a020601000205082770070a2a080c05070a2a050c030a0510000a00110f3800040d05160b00010b05010b030107041111270a0510010a013801041c05250b00010b05010b030107041111270b050f010a0138020c040a041002140a00110f210432053b0b00010b04010b030107071113270a04100338050a02260442054b0b00010b04010b030107091111270a00110f0a040f030a02381938120b030f110b00110f0b010a041005140a041006140b020a04100338050a041007140a041008140a041009140b04100a14120b38140207010002050842a901070a2a080c0b070a2a050c060a0b10000a00110f3800040d05160b00010b0b010b060107041111270a0b10010a013801041c05250b00010b0b010b060107041111270b0b0f010a0138020c0a401c00000000000000000c0d0a0a1002140a00110f210434053d0b00010b0a010b060107071113270e02410d0c090600000000000000000c070a070a0923048b0105470e020a07420d140e030a07421d140e040a07421d140e050a0742101411180c0c0a0a100c0e0c38160c08046005690b00010b0a010b060107051111270a0a0f0c0b083817010d0d0a0c441c0a0a100b0a0c381804770580010b00010b0a010b060107051111270a000a0a0f0b0b0c381011220b07060100000000000000160c0705420b060f100b00110f0b010a0a1005140a0a1006140b0d0a0a100338050a0a1007140a0a1008140a0a1009140b0a100a14120c38130208010003050708439f02070a2a080c14070a2a070f160c11070a2a050c10381b0c170e02410d0c130a13060000000000000000240414051f0b00010b14010b11010b100107081111270e02060000000000000000420d0c0f0e03060000000000000000421d0c0e0a14100f0a0f140a0e141200381c20043a0a140f0f0a0f140a0e141200402b0000000000000000381d0a140f0f0a0f140a0e141200380f0a1114442b401c00000000000000000c160600000000000000000c120a120a132304b001054e0a0f0e020a12420d21045b0a0e0e030a12421d210c0b055d090c0b0b0b0460056f0b00010b14010b11010b10010b0f010b0e0107001111270e020a12420d140e030a12421d140e040a12421d141119110a20048001058f010b00010b14010b11010b10010b0f010b0e0107031111270e020a12420d140e030a12421d140e040a12421d140e050a1242101411180c150d160a15441c0d170a150a000b15060100000000000000111b38070b12060100000000000000160c1205490a100f0d0a00110f0a11140a0f140a0e140a160a060a070a010a080a09120338090a000a0638030c0d0a100f040a00110f0a11140a0f140a0e140a060b060a070a010a080a09120238060a140f010a11140a00110f0a070b0d0b170a0f140a0e140a010a080a090a0a0b1606000000000000000032000000000000000000000000000000000600000000000000001206381e0a140f000a00110f0c0c2e0b0c38002004ff010a140f000a00110f402b0000000000000000381f0b140f000a00110f380b0a1114442b0b100f170b00110f0a11140b0f140b0e140b070b010b080b090b0a120138200a11143201000000000000000000000000000000160b11150209000000011e0a0038213822382312082d080a00320000000000000000000000000000000012072d070a000a0038240a0038250a0038260a0038270a0038280a0038290a00382a0b00382b12052d05020a00000001060601000000000000000b0011342120020b010401084876070a2a080c090a010a0212000c030a09100f0a03381c040d05130b00010b0901063f05000000000000270a09100f0b03382c0c07404a00000000000000000c0a0a07412b0c060600000000000000000c040a040a0623046b05240a070a04422b140c050a0910010a053801042f05370b00010b09010b0701063f05000000000000270a0910010b05382d0c080d0a0a081002140a081007140a08100338050a081005140a081006140a081008140a081009140a08100a140a081018140a08100c140a081014140a081013140b081019141136444a0b04060100000000000000160c04051f0b09010b000b010b020b07140b0a1137382e020c010401084f40070a2a080c030a0310010a013801040905100b00010b030107041111270b0310010b01382d0c020b000a021002140a021007140a02100338050a021005140a021006140a021008140a021009140a02100a140a021018140a02100c140a021014140a021013140b021019141136382f020d0104005087010b010600000000000000002104380a020601000000000000002104150b030b040b050b06070b11250c090c080c070c180c170c16052b0b0206020000000000000021041a051f0b000107021111270b030b040b050b06070b11260c090c080c070c180c170c160b160b170b180b070b080b090c150c140c130c120c110c10056b0a020601000000000000002104490b030b040b050b06070b112e0c0f0c0e0c0d0c0c0c0b0c0a055f0b0206020000000000000021044e05530b000107021111270b030b040b050b06070b112f0c0f0c0e0c0d0c0c0c0b0c0a0b0a0b0b0b0c0b0d0b0e0b0f0c150c140c130c120c110c100b100b110b120b130b140b150c1a0c1d0c190c1b0c1c310021047a057e0b0001064705000000000000270b000b1c0b1b0b190b1d0b1a11393830020e01040108521b070a2a080c030a0310000a0138000409050f0b00010b0301063f05000000000000270b0310000a0138310c020b000b010b0214113a383202080108000600060205030604060506010606060706080603060a050205060802050405050501060c060b0507070005000609060d00"; + let res = run_binary_test("sample_pool", code); + assert!(res.is_ok(), "{:?}", res) +} + +#[test] +fn sample_farming() { + let code = "a11ceb0b050000000e01001e021e2603447c04c00158059802c80107e003bb04089b08a00106bb09e101109c0b780a940c3e0bd20c040cd60cd10d0da71a080eaf1a060000010101020103010401050106000700080209020a0309030a0409040a000b0800000c0e0200010001000d0c0200010001011106000513070002230401000107240000000e000100000f0201020000032104050001220607000525090a000e26010c0200000c26010c0200000a26010c0200000427001200022812140100022915160100022a17010100082b150101000d2c1a010200000b2c1a01020000092c1a010200000d2d1b010200000b2d1b01020000092d1b01020000062e011400050b050d050e050f05100511060b060d060e060f06100611070b070d070e070f0710071109130a130b1309180a180b1809190a190b190c130c180d0b0e0b0f0b0d0d0e0d0f0d0d0e0d100e0e0e100f0e0f10100b110b120b01060c0009060c0303030303030303020c080302060c0501080301060803010c2001010101010101010101030303030308040b050108060b050109000b050109010708000b0102090009010b0102090009010b020209000901070b020209000901050c0a0b0102090009010503030303010a0201080402090009010101020901090002080609000209000806020806090102090108060105010900010302060c03010b0501090002050b0501090001090101080603060c030305060c03030303010b010209000901076661726d696e67076163636f756e7404636f696e107265736f757263655f6163636f756e74067369676e657206737472696e670974696d657374616d700d6661756365745f746f6b656e73076c656e64696e6706726f7574657204737761700a4d6f64756c65446174610c506f736974696f6e496e666f0f506f736974696f6e496e666f4465780b696e69745f6d6f64756c65166c657665726167655f7969656c645f6661726d696e670a7369676e65725f636170105369676e65724361706162696c697479086465785f6e616d6506537472696e670b7369676e65725f616464720a637265617465645f617406737461747573086c657665726167650e737570706c79416d6f756e745f780e737570706c79416d6f756e745f790e737570706c79416d6f756e745f7a0e626f72726f77416d6f756e745f780e626f72726f77416d6f756e745f790e626f72726f77416d6f756e745f7a10706f736974696f6e496e666f5f70616e10706f736974696f6e496e666f5f6c697110706f736974696f6e496e666f5f6175781d72657472696576655f7265736f757263655f6163636f756e745f6361701d6372656174655f7369676e65725f776974685f6361706162696c69747904436f696e03455a4d04757466380f69735f706169725f637265617465640a616464726573735f6f660762616c616e6365087769746864726177076465706f73697406626f72726f7710737761705f65786163745f696e7075740d6164645f6c69717569646974790b6e6f775f7365636f6e64734d63574ba8d90a5926e2866d8291e57683108a47b96d884232a871fe4feddf4100000000000000000000000000000000000000000000000000000000000000015e40a5bf7ab741784d3a99d96d8e2ddc6706ee06e5f509a3314a74c9e53746f5b30dd6a14dd7626ac8a37bc964914f07e3dc38d629637f1087f9f7186f1e0909c4911c40cf758ec21c0ebf0e547933ef6bb0f53ad581c08d2ecc7ad11364be1b030804000000000000000520f67b2452fd82768002ec6c28568713b9359a596585dc1a4bf85fce6b0e3754020308020000000000000003080300000000000000030801000000000000000308ffffffffffffffff0410e80300000000000000000000000000000308000000000000000005204d63574ba8d90a5926e2866d8291e57683108a47b96d884232a871fe4feddf41052000000000000000000000000000000000000000000000000000000000000000000a020c0b50616e63616b65537761700a020b0a4c6971756964537761700a020d0c4155582045786368616e6765126170746f733a3a6d657461646174615f763064030100000000000000164552524f525f4e4f545f435245415445445f50414952000200000000000000184552524f525f494e53554646494349454e545f4153534554000300000000000000174552524f525f494e56414c49445f504152414d5f4445580000020110080301020b1208041405150316011703180319031a031b031c031d030202031e0a0b0102090009011f0a0b010209000901200a0b010209000901020b010b00000000030c0b00070111020c020e0211030c010e010b0212002d000201010402000208ee04070a1104010a010600000000000000002103080536070a11040c183800030e0511080c09051338010c090b0903190b00010704273802031c051f080c0b052138030c0b0b0b03270b00010704273804032a052d080c0c052f38050c0c0b0c03350b0001070427059f010a0106010000000000000021033b0569070b11040c18380603410544080c0d054638070c0d0b0d034c0b00010704273808034f0552080c0e055438090c0e0b0e035a0b0001070427380a035d0560080c0f0562380b0c0f0b0f03680b0001070427059f010a0106020000000000000021036e059b01070c11040c18380c03740577080c100579380d0c100b10037f0b0001070427380e038201058501080c11058701380f0c110b11038d010b00010704273810039001059301080c1205950138110c120b12039f010b00010704270b000107032707082a000c1c0b1c100011030c220e2211080c210a030600000000000000002403ae0105c1010a00110838120c160b160a032403ba010b00010702270a000a0338130c1a07080b1a38140a040600000000000000002403c60105d9010a00110838150c170b170a042403d2010b00010702270a000a0438160c1b07080b1b38170a050600000000000000002403de0105f1010a00110838180c150b150a052403ea010b00010702270a000a0538190c1907080b19381a0a060600000000000000002403f60105f9010e220a06381b0a070600000000000000002403fe010581020e220a07381c0a0806000000000000000024038502070838120c26070838150c280a030a06160602000000000000001a0600000000000000002403940205bd020a010600000000000000002103990205a2020e220a030a06160602000000000000001a060000000000000000381d05bd020a010601000000000000002103a70205b0020e220a030a06160602000000000000001a060000000000000000381e05bd020a010602000000000000002103b50205bd020e220a030a06160602000000000000001a060000000000000000381f0a040a07160602000000000000001a0600000000000000002403c60205ef020a010600000000000000002103cb0205d4020e220a040a07160602000000000000001a060000000000000000382005ef020a010601000000000000002103d90205e2020e220a040a07160602000000000000001a060000000000000000382105ef020a010602000000000000002103e70205ef020e220a040a07160602000000000000001a06000000000000000038220a050a08160602000000000000001a0600000000000000002403f80205b9030a010600000000000000002103fd02058e030e220a050a08160602000000000000001a06000000000000000038230e220a050a08160602000000000000001a060000000000000000382405b9030a010601000000000000002103930305a4030e220a050a08160602000000000000001a06000000000000000038250e220a050a08160602000000000000001a060000000000000000382605b9030a010602000000000000002103a90305b9030e220a050a08160602000000000000001a06000000000000000038270e220a050a08160602000000000000001a0600000000000000003828070838120c25070838150c270a030b25160b26170c130a040b27160b28170c140a130600000000000000002403d00305d5030a14060000000000000000240c0a05d703090c0a0b0a03da0305eb040a010600000000000000002103df0305e6030e220b130b14060000000000000000060000000000000000382905fd030a010601000000000000002103eb0305f2030e220b130b14060000000000000000060000000000000000382a05fd030a010602000000000000002103f70305fd030e220b130b14060000000000000000060000000000000000382b0b0011080c240a213b002003850405ba040b180b241113080b020b030b040b050b060b070b0839010c1d401c000000000000000001401c0000000000000000401c0000000000000000401c000000000000000039000c1f0a0106000000000000000021039e0405a3040d1f36000b1d441c05b6040a010601000000000000002103a80405ad040d1f36010b1d441c05b6040b010602000000000000002103b20405b6040d1f36020b1d441c0e220b1f3f0005ea040b213c000c200b180b241113080b020b030b040b050b060b070b0839010c1e0a010600000000000000002103cf0405d4040b2036000b1e441c05ea040a010601000000000000002103d90405de040b2036010b1e441c05ea040b010602000000000000002103e30405e8040b2036020b1e441c05ea040b200105ed040b0001020000020002010202010b020b030b00"; + let res = run_binary_test("sample_farming", code); + assert!(res.is_ok(), "{:?}", res) +} + +#[test] +fn sample_whitelist() { + let code = "a11ceb0b050000000c01000602060c03123a044c0805545707ab01660891024006d102988b0210e98d02d7010ac08f02090cc98f02a2470debd6020200000101010200030800020a04020301000100040001000005020100000603040000070201000008000100010b0203000204070102030002060a04020300020c010c02030402080d0e020300060607060806090602060c050001060c01050101020507080002050203070b010209000901090009010305070b010205020708000106080002060b0102090009010900010b01020502010b01020900090102070b01020900090109000109010977686974656c697374067369676e6572057461626c650957686974656c69737403616464086164645f6d616e7908636f6e7461696e730a696e697469616c697a650672656d6f766507656e7472696573055461626c650a616464726573735f6f66036e65774419523fdfa01e96fc7c18b67d900be8c863459e25383a5c661b9523631811c1000000000000000000000000000000000000000000000000000000000000000103082003000000000000030822030000000000000308210300000000000005204419523fdfa01e96fc7c18b67d900be8c863459e25383a5c661b9523631811c1052000000000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000000105200000000000000000000000000000000000000000000000000000000000000002052000000000000000000000000000000000000000000000000000000000000000030520000000000000000000000000000000000000000000000000000000000000000405200000000000000000000000000000000000000000000000000000000000000005052000000000000000000000000000000000000000000000000000000000000000060520000000000000000000000000000000000000000000000000000000000000000705200000000000000000000000000000000000000000000000000000000000000008052000000000000000000000000000000000000000000000000000000000000000090520000000000000000000000000000000000000000000000000000000000000001005200000000000000000000000000000000000000000000000000000000000000011052000000000000000000000000000000000000000000000000000000000000000120520000000000000000000000000000000000000000000000000000000000000001305200000000000000000000000000000000000000000000000000000000000000014052000000000000000000000000000000000000000000000000000000000000000150520000000000000000000000000000000000000000000000000000000000000001605200000000000000000000000000000000000000000000000000000000000000017052000000000000000000000000000000000000000000000000000000000000000180520000000000000000000000000000000000000000000000000000000000000001905200000000000000000000000000000000000000000000000000000000000000020052000000000000000000000000000000000000000000000000000000000000000210520000000000000000000000000000000000000000000000000000000000000002205200000000000000000000000000000000000000000000000000000000000000023052000000000000000000000000000000000000000000000000000000000000000240520000000000000000000000000000000000000000000000000000000000000002505200000000000000000000000000000000000000000000000000000000000000026052000000000000000000000000000000000000000000000000000000000000000270520000000000000000000000000000000000000000000000000000000000000002805200000000000000000000000000000000000000000000000000000000000000029052000000000000000000000000000000000000000000000000000000000000000300520000000000000000000000000000000000000000000000000000000000000003105200000000000000000000000000000000000000000000000000000000000000032052000000000000000000000000000000000000000000000000000000000000000330520000000000000000000000000000000000000000000000000000000000000003405200000000000000000000000000000000000000000000000000000000000000035052000000000000000000000000000000000000000000000000000000000000000360520000000000000000000000000000000000000000000000000000000000000003705200000000000000000000000000000000000000000000000000000000000000038052000000000000000000000000000000000000000000000000000000000000000390520000000000000000000000000000000000000000000000000000000000000004005200000000000000000000000000000000000000000000000000000000000000041052000000000000000000000000000000000000000000000000000000000000000420520000000000000000000000000000000000000000000000000000000000000004305200000000000000000000000000000000000000000000000000000000000000044052000000000000000000000000000000000000000000000000000000000000000450520000000000000000000000000000000000000000000000000000000000000004605200000000000000000000000000000000000000000000000000000000000000047052000000000000000000000000000000000000000000000000000000000000000480520000000000000000000000000000000000000000000000000000000000000004905200000000000000000000000000000000000000000000000000000000000000050052000000000000000000000000000000000000000000000000000000000000000510520000000000000000000000000000000000000000000000000000000000000005205200000000000000000000000000000000000000000000000000000000000000053052000000000000000000000000000000000000000000000000000000000000000540520000000000000000000000000000000000000000000000000000000000000005505200000000000000000000000000000000000000000000000000000000000000056052000000000000000000000000000000000000000000000000000000000000000570520000000000000000000000000000000000000000000000000000000000000005805200000000000000000000000000000000000000000000000000000000000000059052000000000000000000000000000000000000000000000000000000000000000600520000000000000000000000000000000000000000000000000000000000000006105200000000000000000000000000000000000000000000000000000000000000062052000000000000000000000000000000000000000000000000000000000000000630520000000000000000000000000000000000000000000000000000000000000006405200000000000000000000000000000000000000000000000000000000000000065052000000000000000000000000000000000000000000000000000000000000000660520000000000000000000000000000000000000000000000000000000000000006705200000000000000000000000000000000000000000000000000000000000000068052000000000000000000000000000000000000000000000000000000000000000690520000000000000000000000000000000000000000000000000000000000000007005200000000000000000000000000000000000000000000000000000000000000071052000000000000000000000000000000000000000000000000000000000000000720520000000000000000000000000000000000000000000000000000000000000007305200000000000000000000000000000000000000000000000000000000000000074052000000000000000000000000000000000000000000000000000000000000000750520000000000000000000000000000000000000000000000000000000000000007605200000000000000000000000000000000000000000000000000000000000000077052000000000000000000000000000000000000000000000000000000000000000780520000000000000000000000000000000000000000000000000000000000000007905200000000000000000000000000000000000000000000000000000000000000080052000000000000000000000000000000000000000000000000000000000000000810520000000000000000000000000000000000000000000000000000000000000008205200000000000000000000000000000000000000000000000000000000000000083052000000000000000000000000000000000000000000000000000000000000000840520000000000000000000000000000000000000000000000000000000000000008505200000000000000000000000000000000000000000000000000000000000000086052000000000000000000000000000000000000000000000000000000000000000870520000000000000000000000000000000000000000000000000000000000000008805200000000000000000000000000000000000000000000000000000000000000089052000000000000000000000000000000000000000000000000000000000000000900520000000000000000000000000000000000000000000000000000000000000009105200000000000000000000000000000000000000000000000000000000000000092052000000000000000000000000000000000000000000000000000000000000000930520000000000000000000000000000000000000000000000000000000000000009405200000000000000000000000000000000000000000000000000000000000000095052000000000000000000000000000000000000000000000000000000000000000960520000000000000000000000000000000000000000000000000000000000000009705200000000000000000000000000000000000000000000000000000000000000098052000000000000000000000000000000000000000000000000000000000000000990520000000000000000000000000000000000000000000000000000000000000010005200000000000000000000000000000000000000000000000000000000000000101052000000000000000000000000000000000000000000000000000000000000001020520000000000000000000000000000000000000000000000000000000000000010305200000000000000000000000000000000000000000000000000000000000000104052000000000000000000000000000000000000000000000000000000000000001050520000000000000000000000000000000000000000000000000000000000000010605200000000000000000000000000000000000000000000000000000000000000107052000000000000000000000000000000000000000000000000000000000000001080520000000000000000000000000000000000000000000000000000000000000010905200000000000000000000000000000000000000000000000000000000000000110052000000000000000000000000000000000000000000000000000000000000001110520000000000000000000000000000000000000000000000000000000000000011205200000000000000000000000000000000000000000000000000000000000000113052000000000000000000000000000000000000000000000000000000000000001140520000000000000000000000000000000000000000000000000000000000000011505200000000000000000000000000000000000000000000000000000000000000116052000000000000000000000000000000000000000000000000000000000000001170520000000000000000000000000000000000000000000000000000000000000011805200000000000000000000000000000000000000000000000000000000000000119052000000000000000000000000000000000000000000000000000000000000001200520000000000000000000000000000000000000000000000000000000000000012105200000000000000000000000000000000000000000000000000000000000000122052000000000000000000000000000000000000000000000000000000000000001230520000000000000000000000000000000000000000000000000000000000000012405200000000000000000000000000000000000000000000000000000000000000125052000000000000000000000000000000000000000000000000000000000000001260520000000000000000000000000000000000000000000000000000000000000012705200000000000000000000000000000000000000000000000000000000000000128052000000000000000000000000000000000000000000000000000000000000001290520000000000000000000000000000000000000000000000000000000000000013005200000000000000000000000000000000000000000000000000000000000000131052000000000000000000000000000000000000000000000000000000000000001320520000000000000000000000000000000000000000000000000000000000000013305200000000000000000000000000000000000000000000000000000000000000134052000000000000000000000000000000000000000000000000000000000000001350520000000000000000000000000000000000000000000000000000000000000013605200000000000000000000000000000000000000000000000000000000000000137052000000000000000000000000000000000000000000000000000000000000001380520000000000000000000000000000000000000000000000000000000000000013905200000000000000000000000000000000000000000000000000000000000000140052000000000000000000000000000000000000000000000000000000000000001410520000000000000000000000000000000000000000000000000000000000000014205200000000000000000000000000000000000000000000000000000000000000143052000000000000000000000000000000000000000000000000000000000000001440520000000000000000000000000000000000000000000000000000000000000014505200000000000000000000000000000000000000000000000000000000000000146052000000000000000000000000000000000000000000000000000000000000001470520000000000000000000000000000000000000000000000000000000000000014805200000000000000000000000000000000000000000000000000000000000000149052000000000000000000000000000000000000000000000000000000000000001500520000000000000000000000000000000000000000000000000000000000000015105200000000000000000000000000000000000000000000000000000000000000152052000000000000000000000000000000000000000000000000000000000000001530520000000000000000000000000000000000000000000000000000000000000015405200000000000000000000000000000000000000000000000000000000000000155052000000000000000000000000000000000000000000000000000000000000001560520000000000000000000000000000000000000000000000000000000000000015705200000000000000000000000000000000000000000000000000000000000000158052000000000000000000000000000000000000000000000000000000000000001590520000000000000000000000000000000000000000000000000000000000000016005200000000000000000000000000000000000000000000000000000000000000161052000000000000000000000000000000000000000000000000000000000000001620520000000000000000000000000000000000000000000000000000000000000016305200000000000000000000000000000000000000000000000000000000000000164052000000000000000000000000000000000000000000000000000000000000001650520000000000000000000000000000000000000000000000000000000000000016605200000000000000000000000000000000000000000000000000000000000000167052000000000000000000000000000000000000000000000000000000000000001680520000000000000000000000000000000000000000000000000000000000000016905200000000000000000000000000000000000000000000000000000000000000170052000000000000000000000000000000000000000000000000000000000000001710520000000000000000000000000000000000000000000000000000000000000017205200000000000000000000000000000000000000000000000000000000000000173052000000000000000000000000000000000000000000000000000000000000001740520000000000000000000000000000000000000000000000000000000000000017505200000000000000000000000000000000000000000000000000000000000000176052000000000000000000000000000000000000000000000000000000000000001770520000000000000000000000000000000000000000000000000000000000000017805200000000000000000000000000000000000000000000000000000000000000179052000000000000000000000000000000000000000000000000000000000000001800520000000000000000000000000000000000000000000000000000000000000018105200000000000000000000000000000000000000000000000000000000000000182052000000000000000000000000000000000000000000000000000000000000001830520000000000000000000000000000000000000000000000000000000000000018405200000000000000000000000000000000000000000000000000000000000000185052000000000000000000000000000000000000000000000000000000000000001860520000000000000000000000000000000000000000000000000000000000000018705200000000000000000000000000000000000000000000000000000000000000188052000000000000000000000000000000000000000000000000000000000000001890520000000000000000000000000000000000000000000000000000000000000019005200000000000000000000000000000000000000000000000000000000000000191052000000000000000000000000000000000000000000000000000000000000001920520000000000000000000000000000000000000000000000000000000000000019305200000000000000000000000000000000000000000000000000000000000000194052000000000000000000000000000000000000000000000000000000000000001950520000000000000000000000000000000000000000000000000000000000000019605200000000000000000000000000000000000000000000000000000000000000197052000000000000000000000000000000000000000000000000000000000000001980520000000000000000000000000000000000000000000000000000000000000019905200000000000000000000000000000000000000000000000000000000000000200052000000000000000000000000000000000000000000000000000000000000002010520000000000000000000000000000000000000000000000000000000000000020205200000000000000000000000000000000000000000000000000000000000000203052000000000000000000000000000000000000000000000000000000000000002040520000000000000000000000000000000000000000000000000000000000000020505200000000000000000000000000000000000000000000000000000000000000206052000000000000000000000000000000000000000000000000000000000000002070520000000000000000000000000000000000000000000000000000000000000020805200000000000000000000000000000000000000000000000000000000000000209052000000000000000000000000000000000000000000000000000000000000002100520000000000000000000000000000000000000000000000000000000000000021105200000000000000000000000000000000000000000000000000000000000000212052000000000000000000000000000000000000000000000000000000000000002130520000000000000000000000000000000000000000000000000000000000000021405200000000000000000000000000000000000000000000000000000000000000215052000000000000000000000000000000000000000000000000000000000000002160520000000000000000000000000000000000000000000000000000000000000021705200000000000000000000000000000000000000000000000000000000000000218052000000000000000000000000000000000000000000000000000000000000002190520000000000000000000000000000000000000000000000000000000000000022005200000000000000000000000000000000000000000000000000000000000000221052000000000000000000000000000000000000000000000000000000000000002220520000000000000000000000000000000000000000000000000000000000000022305200000000000000000000000000000000000000000000000000000000000000224052000000000000000000000000000000000000000000000000000000000000002250520000000000000000000000000000000000000000000000000000000000000022605200000000000000000000000000000000000000000000000000000000000000227052000000000000000000000000000000000000000000000000000000000000002280520000000000000000000000000000000000000000000000000000000000000022905200000000000000000000000000000000000000000000000000000000000000230052000000000000000000000000000000000000000000000000000000000000002310520000000000000000000000000000000000000000000000000000000000000023205200000000000000000000000000000000000000000000000000000000000000233052000000000000000000000000000000000000000000000000000000000000002340520000000000000000000000000000000000000000000000000000000000000023505200000000000000000000000000000000000000000000000000000000000000236052000000000000000000000000000000000000000000000000000000000000002370520000000000000000000000000000000000000000000000000000000000000023805200000000000000000000000000000000000000000000000000000000000000239052000000000000000000000000000000000000000000000000000000000000002400520000000000000000000000000000000000000000000000000000000000000024105200000000000000000000000000000000000000000000000000000000000000242052000000000000000000000000000000000000000000000000000000000000002430520000000000000000000000000000000000000000000000000000000000000024405200000000000000000000000000000000000000000000000000000000000000245052000000000000000000000000000000000000000000000000000000000000002460520000000000000000000000000000000000000000000000000000000000000024705200000000000000000000000000000000000000000000000000000000000000248052000000000000000000000000000000000000000000000000000000000000002490520000000000000000000000000000000000000000000000000000000000000025005200000000000000000000000000000000000000000000000000000000000000251052000000000000000000000000000000000000000000000000000000000000002520520000000000000000000000000000000000000000000000000000000000000025305200000000000000000000000000000000000000000000000000000000000000254052000000000000000000000000000000000000000000000000000000000000002550520000000000000000000000000000000000000000000000000000000000000025605200000000000000000000000000000000000000000000000000000000000000257052000000000000000000000000000000000000000000000000000000000000002580520000000000000000000000000000000000000000000000000000000000000025905200000000000000000000000000000000000000000000000000000000000000260052000000000000000000000000000000000000000000000000000000000000002610520000000000000000000000000000000000000000000000000000000000000026205200000000000000000000000000000000000000000000000000000000000000263052000000000000000000000000000000000000000000000000000000000000002640520000000000000000000000000000000000000000000000000000000000000026505200000000000000000000000000000000000000000000000000000000000000266052000000000000000000000000000000000000000000000000000000000000002670520000000000000000000000000000000000000000000000000000000000000026805200000000000000000000000000000000000000000000000000000000000000269052000000000000000000000000000000000000000000000000000000000000002700520000000000000000000000000000000000000000000000000000000000000027105200000000000000000000000000000000000000000000000000000000000000272052000000000000000000000000000000000000000000000000000000000000002730520000000000000000000000000000000000000000000000000000000000000027405200000000000000000000000000000000000000000000000000000000000000275052000000000000000000000000000000000000000000000000000000000000002760520000000000000000000000000000000000000000000000000000000000000027705200000000000000000000000000000000000000000000000000000000000000278052000000000000000000000000000000000000000000000000000000000000002790520000000000000000000000000000000000000000000000000000000000000028005200000000000000000000000000000000000000000000000000000000000000281052000000000000000000000000000000000000000000000000000000000000002820520000000000000000000000000000000000000000000000000000000000000028305200000000000000000000000000000000000000000000000000000000000000284052000000000000000000000000000000000000000000000000000000000000002850520000000000000000000000000000000000000000000000000000000000000028605200000000000000000000000000000000000000000000000000000000000000287052000000000000000000000000000000000000000000000000000000000000002880520000000000000000000000000000000000000000000000000000000000000028905200000000000000000000000000000000000000000000000000000000000000290052000000000000000000000000000000000000000000000000000000000000002910520000000000000000000000000000000000000000000000000000000000000029205200000000000000000000000000000000000000000000000000000000000000293052000000000000000000000000000000000000000000000000000000000000002940520000000000000000000000000000000000000000000000000000000000000029505200000000000000000000000000000000000000000000000000000000000000296052000000000000000000000000000000000000000000000000000000000000002970520000000000000000000000000000000000000000000000000000000000000029805200000000000000000000000000000000000000000000000000000000000000299052000000000000000000000000000000000000000000000000000000000000003000520000000000000000000000000000000000000000000000000000000000000030105200000000000000000000000000000000000000000000000000000000000000302052000000000000000000000000000000000000000000000000000000000000003030520000000000000000000000000000000000000000000000000000000000000030405200000000000000000000000000000000000000000000000000000000000000305052000000000000000000000000000000000000000000000000000000000000003060520000000000000000000000000000000000000000000000000000000000000030705200000000000000000000000000000000000000000000000000000000000000308052000000000000000000000000000000000000000000000000000000000000003090520000000000000000000000000000000000000000000000000000000000000031005200000000000000000000000000000000000000000000000000000000000000311052000000000000000000000000000000000000000000000000000000000000003120520000000000000000000000000000000000000000000000000000000000000031305200000000000000000000000000000000000000000000000000000000000000314052000000000000000000000000000000000000000000000000000000000000003150520000000000000000000000000000000000000000000000000000000000000031605200000000000000000000000000000000000000000000000000000000000000317052000000000000000000000000000000000000000000000000000000000000003180520000000000000000000000000000000000000000000000000000000000000031905200000000000000000000000000000000000000000000000000000000000000320052000000000000000000000000000000000000000000000000000000000000003210520000000000000000000000000000000000000000000000000000000000000032205200000000000000000000000000000000000000000000000000000000000000323052000000000000000000000000000000000000000000000000000000000000003240520000000000000000000000000000000000000000000000000000000000000032505200000000000000000000000000000000000000000000000000000000000000326052000000000000000000000000000000000000000000000000000000000000003270520000000000000000000000000000000000000000000000000000000000000032805200000000000000000000000000000000000000000000000000000000000000329052000000000000000000000000000000000000000000000000000000000000003300520000000000000000000000000000000000000000000000000000000000000033105200000000000000000000000000000000000000000000000000000000000000332052000000000000000000000000000000000000000000000000000000000000003330520000000000000000000000000000000000000000000000000000000000000033405200000000000000000000000000000000000000000000000000000000000000335052000000000000000000000000000000000000000000000000000000000000003360520000000000000000000000000000000000000000000000000000000000000033705200000000000000000000000000000000000000000000000000000000000000338052000000000000000000000000000000000000000000000000000000000000003390520000000000000000000000000000000000000000000000000000000000000034005200000000000000000000000000000000000000000000000000000000000000341052000000000000000000000000000000000000000000000000000000000000003420520000000000000000000000000000000000000000000000000000000000000034305200000000000000000000000000000000000000000000000000000000000000344052000000000000000000000000000000000000000000000000000000000000003450520000000000000000000000000000000000000000000000000000000000000034605200000000000000000000000000000000000000000000000000000000000000347052000000000000000000000000000000000000000000000000000000000000003480520000000000000000000000000000000000000000000000000000000000000034905200000000000000000000000000000000000000000000000000000000000000350052000000000000000000000000000000000000000000000000000000000000003510520000000000000000000000000000000000000000000000000000000000000035205200000000000000000000000000000000000000000000000000000000000000353052000000000000000000000000000000000000000000000000000000000000003540520000000000000000000000000000000000000000000000000000000000000035505200000000000000000000000000000000000000000000000000000000000000356052000000000000000000000000000000000000000000000000000000000000003570520000000000000000000000000000000000000000000000000000000000000035805200000000000000000000000000000000000000000000000000000000000000359052000000000000000000000000000000000000000000000000000000000000003600520000000000000000000000000000000000000000000000000000000000000036105200000000000000000000000000000000000000000000000000000000000000362052000000000000000000000000000000000000000000000000000000000000003630520000000000000000000000000000000000000000000000000000000000000036405200000000000000000000000000000000000000000000000000000000000000365052000000000000000000000000000000000000000000000000000000000000003660520000000000000000000000000000000000000000000000000000000000000036705200000000000000000000000000000000000000000000000000000000000000368052000000000000000000000000000000000000000000000000000000000000003690520000000000000000000000000000000000000000000000000000000000000037005200000000000000000000000000000000000000000000000000000000000000371052000000000000000000000000000000000000000000000000000000000000003720520000000000000000000000000000000000000000000000000000000000000037305200000000000000000000000000000000000000000000000000000000000000374052000000000000000000000000000000000000000000000000000000000000003750520000000000000000000000000000000000000000000000000000000000000037605200000000000000000000000000000000000000000000000000000000000000377052000000000000000000000000000000000000000000000000000000000000003780520000000000000000000000000000000000000000000000000000000000000037905200000000000000000000000000000000000000000000000000000000000000380052000000000000000000000000000000000000000000000000000000000000003810520000000000000000000000000000000000000000000000000000000000000038205200000000000000000000000000000000000000000000000000000000000000383052000000000000000000000000000000000000000000000000000000000000003840520000000000000000000000000000000000000000000000000000000000000038505200000000000000000000000000000000000000000000000000000000000000386052000000000000000000000000000000000000000000000000000000000000003870520000000000000000000000000000000000000000000000000000000000000038805200000000000000000000000000000000000000000000000000000000000000389052000000000000000000000000000000000000000000000000000000000000003900520000000000000000000000000000000000000000000000000000000000000039105200000000000000000000000000000000000000000000000000000000000000392052000000000000000000000000000000000000000000000000000000000000003930520000000000000000000000000000000000000000000000000000000000000039405200000000000000000000000000000000000000000000000000000000000000395052000000000000000000000000000000000000000000000000000000000000003960520000000000000000000000000000000000000000000000000000000000000039705200000000000000000000000000000000000000000000000000000000000000398052000000000000000000000000000000000000000000000000000000000000003990520000000000000000000000000000000000000000000000000000000000000040005200000000000000000000000000000000000000000000000000000000000000401052000000000000000000000000000000000000000000000000000000000000004020520000000000000000000000000000000000000000000000000000000000000040305200000000000000000000000000000000000000000000000000000000000000404052000000000000000000000000000000000000000000000000000000000000004050520000000000000000000000000000000000000000000000000000000000000040605200000000000000000000000000000000000000000000000000000000000000407052000000000000000000000000000000000000000000000000000000000000004080520000000000000000000000000000000000000000000000000000000000000040905200000000000000000000000000000000000000000000000000000000000000410052000000000000000000000000000000000000000000000000000000000000004110520000000000000000000000000000000000000000000000000000000000000041205200000000000000000000000000000000000000000000000000000000000000413052000000000000000000000000000000000000000000000000000000000000004140520000000000000000000000000000000000000000000000000000000000000041505200000000000000000000000000000000000000000000000000000000000000416052000000000000000000000000000000000000000000000000000000000000004170520000000000000000000000000000000000000000000000000000000000000041805200000000000000000000000000000000000000000000000000000000000000419052000000000000000000000000000000000000000000000000000000000000004200520000000000000000000000000000000000000000000000000000000000000042105200000000000000000000000000000000000000000000000000000000000000422052000000000000000000000000000000000000000000000000000000000000004230520000000000000000000000000000000000000000000000000000000000000042405200000000000000000000000000000000000000000000000000000000000000425052000000000000000000000000000000000000000000000000000000000000004260520000000000000000000000000000000000000000000000000000000000000042705200000000000000000000000000000000000000000000000000000000000000428052000000000000000000000000000000000000000000000000000000000000004290520000000000000000000000000000000000000000000000000000000000000043005200000000000000000000000000000000000000000000000000000000000000431052000000000000000000000000000000000000000000000000000000000000004320520000000000000000000000000000000000000000000000000000000000000043305200000000000000000000000000000000000000000000000000000000000000434052000000000000000000000000000000000000000000000000000000000000004350520000000000000000000000000000000000000000000000000000000000000043605200000000000000000000000000000000000000000000000000000000000000437052000000000000000000000000000000000000000000000000000000000000004380520000000000000000000000000000000000000000000000000000000000000043905200000000000000000000000000000000000000000000000000000000000000440052000000000000000000000000000000000000000000000000000000000000004410520000000000000000000000000000000000000000000000000000000000000044205200000000000000000000000000000000000000000000000000000000000000443052000000000000000000000000000000000000000000000000000000000000004440520000000000000000000000000000000000000000000000000000000000000044505200000000000000000000000000000000000000000000000000000000000000446052000000000000000000000000000000000000000000000000000000000000004470520000000000000000000000000000000000000000000000000000000000000044805200000000000000000000000000000000000000000000000000000000000000449052000000000000000000000000000000000000000000000000000000000000004500520000000000000000000000000000000000000000000000000000000000000045105200000000000000000000000000000000000000000000000000000000000000452052000000000000000000000000000000000000000000000000000000000000004530520000000000000000000000000000000000000000000000000000000000000045405200000000000000000000000000000000000000000000000000000000000000455052000000000000000000000000000000000000000000000000000000000000004560520000000000000000000000000000000000000000000000000000000000000045705200000000000000000000000000000000000000000000000000000000000000458052000000000000000000000000000000000000000000000000000000000000004590520000000000000000000000000000000000000000000000000000000000000046005200000000000000000000000000000000000000000000000000000000000000461052000000000000000000000000000000000000000000000000000000000000004620520000000000000000000000000000000000000000000000000000000000000046305200000000000000000000000000000000000000000000000000000000000000464052000000000000000000000000000000000000000000000000000000000000004650520000000000000000000000000000000000000000000000000000000000000046605200000000000000000000000000000000000000000000000000000000000000467052000000000000000000000000000000000000000000000000000000000000004680520000000000000000000000000000000000000000000000000000000000000046905200000000000000000000000000000000000000000000000000000000000000470052000000000000000000000000000000000000000000000000000000000000004710520000000000000000000000000000000000000000000000000000000000000047205200000000000000000000000000000000000000000000000000000000000000473052000000000000000000000000000000000000000000000000000000000000004740520000000000000000000000000000000000000000000000000000000000000047505200000000000000000000000000000000000000000000000000000000000000476052000000000000000000000000000000000000000000000000000000000000004770520000000000000000000000000000000000000000000000000000000000000047805200000000000000000000000000000000000000000000000000000000000000479052000000000000000000000000000000000000000000000000000000000000004800520000000000000000000000000000000000000000000000000000000000000048105200000000000000000000000000000000000000000000000000000000000000482052000000000000000000000000000000000000000000000000000000000000004830520000000000000000000000000000000000000000000000000000000000000048405200000000000000000000000000000000000000000000000000000000000000485052000000000000000000000000000000000000000000000000000000000000004860520000000000000000000000000000000000000000000000000000000000000048705200000000000000000000000000000000000000000000000000000000000000488052000000000000000000000000000000000000000000000000000000000000004890520000000000000000000000000000000000000000000000000000000000000049005200000000000000000000000000000000000000000000000000000000000000491052000000000000000000000000000000000000000000000000000000000000004920520000000000000000000000000000000000000000000000000000000000000049305200000000000000000000000000000000000000000000000000000000000000494052000000000000000000000000000000000000000000000000000000000000004950520000000000000000000000000000000000000000000000000000000000000049605200000000000000000000000000000000000000000000000000000000000000497052000000000000000000000000000000000000000000000000000000000000004980520000000000000000000000000000000000000000000000000000000000000049905200000000000000000000000000000000000000000000000000000000000000500052000000000000000000000000000000000000000000000000000000000000005010520000000000000000000000000000000000000000000000000000000000000050205200000000000000000000000000000000000000000000000000000000000000503052000000000000000000000000000000000000000000000000000000000000005040520000000000000000000000000000000000000000000000000000000000000050505200000000000000000000000000000000000000000000000000000000000000506052000000000000000000000000000000000000000000000000000000000000005070520000000000000000000000000000000000000000000000000000000000000050805200000000000000000000000000000000000000000000000000000000000000509052000000000000000000000000000000000000000000000000000000000000005100520000000000000000000000000000000000000000000000000000000000000051105200000000000000000000000000000000000000000000000000000000000000512052000000000000000000000000000000000000000000000000000000000000005130520000000000000000000000000000000000000000000000000000000000000051405200000000000000000000000000000000000000000000000000000000000000515052000000000000000000000000000000000000000000000000000000000000005160520000000000000000000000000000000000000000000000000000000000000051705200000000000000000000000000000000000000000000000000000000000000518052000000000000000000000000000000000000000000000000000000000000005190520000000000000000000000000000000000000000000000000000000000000052005200000000000000000000000000000000000000000000000000000000000000521052000000000000000000000000000000000000000000000000000000000000005220520000000000000000000000000000000000000000000000000000000000000052305200000000000000000000000000000000000000000000000000000000000000524052000000000000000000000000000000000000000000000000000000000000005250520000000000000000000000000000000000000000000000000000000000000052605200000000000000000000000000000000000000000000000000000000000000527052000000000000000000000000000000000000000000000000000000000000005280520000000000000000000000000000000000000000000000000000000000000052905200000000000000000000000000000000000000000000000000000000000000530052000000000000000000000000000000000000000000000000000000000000005310520000000000000000000000000000000000000000000000000000000000000053205200000000000000000000000000000000000000000000000000000000000000533052000000000000000000000000000000000000000000000000000000000000005340520000000000000000000000000000000000000000000000000000000000000053505200000000000000000000000000000000000000000000000000000000000000536052000000000000000000000000000000000000000000000000000000000000005370520000000000000000000000000000000000000000000000000000000000000053805200000000000000000000000000000000000000000000000000000000000000539052000000000000000000000000000000000000000000000000000000000000005400520000000000000000000000000000000000000000000000000000000000000054105200000000000000000000000000000000000000000000000000000000000000542052000000000000000000000000000000000000000000000000000000000000005430520000000000000000000000000000000000000000000000000000000000000054405200000000000000000000000000000000000000000000000000000000000000545052000000000000000000000000000000000000000000000000000000000000005460520000000000000000000000000000000000000000000000000000000000000054705200000000000000000000000000000000000000000000000000000000000000548052000000000000000000000000000000000000000000000000000000000000005490520000000000000000000000000000000000000000000000000000000000000055005200000000000000000000000000000000000000000000000000000000000000551052000000000000000000000000000000000000000000000000000000000000005520520000000000000000000000000000000000000000000000000000000000000055305200000000000000000000000000000000000000000000000000000000000000554052000000000000000000000000000000000000000000000000000000000000005550520000000000000000000000000000000000000000000000000000000000000055605200000000000000000000000000000000000000000000000000000000000000557052000000000000000000000000000000000000000000000000000000000000005580520000000000000000000000000000000000000000000000000000000000000055905200000000000000000000000000000000000000000000000000000000000000560052000000000000000000000000000000000000000000000000000000000000005610520000000000000000000000000000000000000000000000000000000000000056205200000000000000000000000000000000000000000000000000000000000000563052000000000000000000000000000000000000000000000000000000000000005640520000000000000000000000000000000000000000000000000000000000000056505200000000000000000000000000000000000000000000000000000000000000566052000000000000000000000000000000000000000000000000000000000000005670520000000000000000000000000000000000000000000000000000000000000056805200000000000000000000000000000000000000000000000000000000000000569052000000000000000000000000000000000000000000000000000000000000005700520000000000000000000000000000000000000000000000000000000000000057105200000000000000000000000000000000000000000000000000000000000000572052000000000000000000000000000000000000000000000000000000000000005730520000000000000000000000000000000000000000000000000000000000000057405200000000000000000000000000000000000000000000000000000000000000575052000000000000000000000000000000000000000000000000000000000000005760520000000000000000000000000000000000000000000000000000000000000057705200000000000000000000000000000000000000000000000000000000000000578052000000000000000000000000000000000000000000000000000000000000005790520000000000000000000000000000000000000000000000000000000000000058005200000000000000000000000000000000000000000000000000000000000000581052000000000000000000000000000000000000000000000000000000000000005820520000000000000000000000000000000000000000000000000000000000000058305200000000000000000000000000000000000000000000000000000000000000584052000000000000000000000000000000000000000000000000000000000000005850520000000000000000000000000000000000000000000000000000000000000058605200000000000000000000000000000000000000000000000000000000000000587052000000000000000000000000000000000000000000000000000000000000005880520000000000000000000000000000000000000000000000000000000000000058905200000000000000000000000000000000000000000000000000000000000000590052000000000000000000000000000000000000000000000000000000000000005910520000000000000000000000000000000000000000000000000000000000000059205200000000000000000000000000000000000000000000000000000000000000593052000000000000000000000000000000000000000000000000000000000000005940520000000000000000000000000000000000000000000000000000000000000059505200000000000000000000000000000000000000000000000000000000000000596052000000000000000000000000000000000000000000000000000000000000005970520000000000000000000000000000000000000000000000000000000000000059805200000000000000000000000000000000000000000000000000000000000000599052000000000000000000000000000000000000000000000000000000000000006000520000000000000000000000000000000000000000000000000000000000000060105200000000000000000000000000000000000000000000000000000000000000602052000000000000000000000000000000000000000000000000000000000000006030520000000000000000000000000000000000000000000000000000000000000060405200000000000000000000000000000000000000000000000000000000000000605052000000000000000000000000000000000000000000000000000000000000006060520000000000000000000000000000000000000000000000000000000000000060705200000000000000000000000000000000000000000000000000000000000000608052000000000000000000000000000000000000000000000000000000000000006090520000000000000000000000000000000000000000000000000000000000000061005200000000000000000000000000000000000000000000000000000000000000611052000000000000000000000000000000000000000000000000000000000000006120520000000000000000000000000000000000000000000000000000000000000061305200000000000000000000000000000000000000000000000000000000000000614052000000000000000000000000000000000000000000000000000000000000006150520000000000000000000000000000000000000000000000000000000000000061605200000000000000000000000000000000000000000000000000000000000000617052000000000000000000000000000000000000000000000000000000000000006180520000000000000000000000000000000000000000000000000000000000000061905200000000000000000000000000000000000000000000000000000000000000620052000000000000000000000000000000000000000000000000000000000000006210520000000000000000000000000000000000000000000000000000000000000062205200000000000000000000000000000000000000000000000000000000000000623052000000000000000000000000000000000000000000000000000000000000006240520000000000000000000000000000000000000000000000000000000000000062505200000000000000000000000000000000000000000000000000000000000000626052000000000000000000000000000000000000000000000000000000000000006270520000000000000000000000000000000000000000000000000000000000000062805200000000000000000000000000000000000000000000000000000000000000629052000000000000000000000000000000000000000000000000000000000000006300520000000000000000000000000000000000000000000000000000000000000063105200000000000000000000000000000000000000000000000000000000000000632052000000000000000000000000000000000000000000000000000000000000006330520000000000000000000000000000000000000000000000000000000000000063405200000000000000000000000000000000000000000000000000000000000000635052000000000000000000000000000000000000000000000000000000000000006360520000000000000000000000000000000000000000000000000000000000000063705200000000000000000000000000000000000000000000000000000000000000638052000000000000000000000000000000000000000000000000000000000000006390520000000000000000000000000000000000000000000000000000000000000064005200000000000000000000000000000000000000000000000000000000000000641052000000000000000000000000000000000000000000000000000000000000006420520000000000000000000000000000000000000000000000000000000000000064305200000000000000000000000000000000000000000000000000000000000000644052000000000000000000000000000000000000000000000000000000000000006450520000000000000000000000000000000000000000000000000000000000000064605200000000000000000000000000000000000000000000000000000000000000647052000000000000000000000000000000000000000000000000000000000000006480520000000000000000000000000000000000000000000000000000000000000064905200000000000000000000000000000000000000000000000000000000000000650052000000000000000000000000000000000000000000000000000000000000006510520000000000000000000000000000000000000000000000000000000000000065205200000000000000000000000000000000000000000000000000000000000000653052000000000000000000000000000000000000000000000000000000000000006540520000000000000000000000000000000000000000000000000000000000000065505200000000000000000000000000000000000000000000000000000000000000656052000000000000000000000000000000000000000000000000000000000000006570520000000000000000000000000000000000000000000000000000000000000065805200000000000000000000000000000000000000000000000000000000000000659052000000000000000000000000000000000000000000000000000000000000006600520000000000000000000000000000000000000000000000000000000000000066105200000000000000000000000000000000000000000000000000000000000000662052000000000000000000000000000000000000000000000000000000000000006630520000000000000000000000000000000000000000000000000000000000000066405200000000000000000000000000000000000000000000000000000000000000665052000000000000000000000000000000000000000000000000000000000000006660520000000000000000000000000000000000000000000000000000000000000066705200000000000000000000000000000000000000000000000000000000000000668052000000000000000000000000000000000000000000000000000000000000006690520000000000000000000000000000000000000000000000000000000000000067005200000000000000000000000000000000000000000000000000000000000000671052000000000000000000000000000000000000000000000000000000000000006720520000000000000000000000000000000000000000000000000000000000000067305200000000000000000000000000000000000000000000000000000000000000674052000000000000000000000000000000000000000000000000000000000000006750520000000000000000000000000000000000000000000000000000000000000067605200000000000000000000000000000000000000000000000000000000000000677052000000000000000000000000000000000000000000000000000000000000006780520000000000000000000000000000000000000000000000000000000000000067905200000000000000000000000000000000000000000000000000000000000000680052000000000000000000000000000000000000000000000000000000000000006810520000000000000000000000000000000000000000000000000000000000000068205200000000000000000000000000000000000000000000000000000000000000683052000000000000000000000000000000000000000000000000000000000000006840520000000000000000000000000000000000000000000000000000000000000068505200000000000000000000000000000000000000000000000000000000000000686052000000000000000000000000000000000000000000000000000000000000006870520000000000000000000000000000000000000000000000000000000000000068805200000000000000000000000000000000000000000000000000000000000000689052000000000000000000000000000000000000000000000000000000000000006900520000000000000000000000000000000000000000000000000000000000000069105200000000000000000000000000000000000000000000000000000000000000692052000000000000000000000000000000000000000000000000000000000000006930520000000000000000000000000000000000000000000000000000000000000069405200000000000000000000000000000000000000000000000000000000000000695052000000000000000000000000000000000000000000000000000000000000006960520000000000000000000000000000000000000000000000000000000000000069705200000000000000000000000000000000000000000000000000000000000000698052000000000000000000000000000000000000000000000000000000000000006990520000000000000000000000000000000000000000000000000000000000000070005200000000000000000000000000000000000000000000000000000000000000701052000000000000000000000000000000000000000000000000000000000000007020520000000000000000000000000000000000000000000000000000000000000070305200000000000000000000000000000000000000000000000000000000000000704052000000000000000000000000000000000000000000000000000000000000007050520000000000000000000000000000000000000000000000000000000000000070605200000000000000000000000000000000000000000000000000000000000000707052000000000000000000000000000000000000000000000000000000000000007080520000000000000000000000000000000000000000000000000000000000000070905200000000000000000000000000000000000000000000000000000000000000710052000000000000000000000000000000000000000000000000000000000000007110520000000000000000000000000000000000000000000000000000000000000071205200000000000000000000000000000000000000000000000000000000000000713052000000000000000000000000000000000000000000000000000000000000007140520000000000000000000000000000000000000000000000000000000000000071505200000000000000000000000000000000000000000000000000000000000000716052000000000000000000000000000000000000000000000000000000000000007170520000000000000000000000000000000000000000000000000000000000000071805200000000000000000000000000000000000000000000000000000000000000719052000000000000000000000000000000000000000000000000000000000000007200520000000000000000000000000000000000000000000000000000000000000072105200000000000000000000000000000000000000000000000000000000000000722052000000000000000000000000000000000000000000000000000000000000007230520000000000000000000000000000000000000000000000000000000000000072405200000000000000000000000000000000000000000000000000000000000000725052000000000000000000000000000000000000000000000000000000000000007260520000000000000000000000000000000000000000000000000000000000000072705200000000000000000000000000000000000000000000000000000000000000728052000000000000000000000000000000000000000000000000000000000000007290520000000000000000000000000000000000000000000000000000000000000073005200000000000000000000000000000000000000000000000000000000000000731052000000000000000000000000000000000000000000000000000000000000007320520000000000000000000000000000000000000000000000000000000000000073305200000000000000000000000000000000000000000000000000000000000000734052000000000000000000000000000000000000000000000000000000000000007350520000000000000000000000000000000000000000000000000000000000000073605200000000000000000000000000000000000000000000000000000000000000737052000000000000000000000000000000000000000000000000000000000000007380520000000000000000000000000000000000000000000000000000000000000073905200000000000000000000000000000000000000000000000000000000000000740052000000000000000000000000000000000000000000000000000000000000007410520000000000000000000000000000000000000000000000000000000000000074205200000000000000000000000000000000000000000000000000000000000000743052000000000000000000000000000000000000000000000000000000000000007440520000000000000000000000000000000000000000000000000000000000000074505200000000000000000000000000000000000000000000000000000000000000746052000000000000000000000000000000000000000000000000000000000000007470520000000000000000000000000000000000000000000000000000000000000074805200000000000000000000000000000000000000000000000000000000000000749052000000000000000000000000000000000000000000000000000000000000007500520000000000000000000000000000000000000000000000000000000000000075105200000000000000000000000000000000000000000000000000000000000000752052000000000000000000000000000000000000000000000000000000000000007530520000000000000000000000000000000000000000000000000000000000000075405200000000000000000000000000000000000000000000000000000000000000755052000000000000000000000000000000000000000000000000000000000000007560520000000000000000000000000000000000000000000000000000000000000075705200000000000000000000000000000000000000000000000000000000000000758052000000000000000000000000000000000000000000000000000000000000007590520000000000000000000000000000000000000000000000000000000000000076005200000000000000000000000000000000000000000000000000000000000000761052000000000000000000000000000000000000000000000000000000000000007620520000000000000000000000000000000000000000000000000000000000000076305200000000000000000000000000000000000000000000000000000000000000764052000000000000000000000000000000000000000000000000000000000000007650520000000000000000000000000000000000000000000000000000000000000076605200000000000000000000000000000000000000000000000000000000000000767052000000000000000000000000000000000000000000000000000000000000007680520000000000000000000000000000000000000000000000000000000000000076905200000000000000000000000000000000000000000000000000000000000000770052000000000000000000000000000000000000000000000000000000000000007710520000000000000000000000000000000000000000000000000000000000000077205200000000000000000000000000000000000000000000000000000000000000773052000000000000000000000000000000000000000000000000000000000000007740520000000000000000000000000000000000000000000000000000000000000077505200000000000000000000000000000000000000000000000000000000000000776052000000000000000000000000000000000000000000000000000000000000007770520000000000000000000000000000000000000000000000000000000000000077805200000000000000000000000000000000000000000000000000000000000000779052000000000000000000000000000000000000000000000000000000000000007800520000000000000000000000000000000000000000000000000000000000000078105200000000000000000000000000000000000000000000000000000000000000782052000000000000000000000000000000000000000000000000000000000000007830520000000000000000000000000000000000000000000000000000000000000078405200000000000000000000000000000000000000000000000000000000000000785052000000000000000000000000000000000000000000000000000000000000007860520000000000000000000000000000000000000000000000000000000000000078705200000000000000000000000000000000000000000000000000000000000000788052000000000000000000000000000000000000000000000000000000000000007890520000000000000000000000000000000000000000000000000000000000000079005200000000000000000000000000000000000000000000000000000000000000791052000000000000000000000000000000000000000000000000000000000000007920520000000000000000000000000000000000000000000000000000000000000079305200000000000000000000000000000000000000000000000000000000000000794052000000000000000000000000000000000000000000000000000000000000007950520000000000000000000000000000000000000000000000000000000000000079605200000000000000000000000000000000000000000000000000000000000000797052000000000000000000000000000000000000000000000000000000000000007980520000000000000000000000000000000000000000000000000000000000000079905200000000000000000000000000000000000000000000000000000000000000800052000000000000000000000000000000000000000000000000000000000000008010520000000000000000000000000000000000000000000000000000000000000080205200000000000000000000000000000000000000000000000000000000000000803052000000000000000000000000000000000000000000000000000000000000008040520000000000000000000000000000000000000000000000000000000000000080505200000000000000000000000000000000000000000000000000000000000000806052000000000000000000000000000000000000000000000000000000000000008070520000000000000000000000000000000000000000000000000000000000000080805200000000000000000000000000000000000000000000000000000000000000809052000000000000000000000000000000000000000000000000000000000000008100520000000000000000000000000000000000000000000000000000000000000081105200000000000000000000000000000000000000000000000000000000000000812052000000000000000000000000000000000000000000000000000000000000008130520000000000000000000000000000000000000000000000000000000000000081405200000000000000000000000000000000000000000000000000000000000000815052000000000000000000000000000000000000000000000000000000000000008160520000000000000000000000000000000000000000000000000000000000000081705200000000000000000000000000000000000000000000000000000000000000818052000000000000000000000000000000000000000000000000000000000000008190520000000000000000000000000000000000000000000000000000000000000082005200000000000000000000000000000000000000000000000000000000000000821052000000000000000000000000000000000000000000000000000000000000008220520000000000000000000000000000000000000000000000000000000000000082305200000000000000000000000000000000000000000000000000000000000000824052000000000000000000000000000000000000000000000000000000000000008250520000000000000000000000000000000000000000000000000000000000000082605200000000000000000000000000000000000000000000000000000000000000827052000000000000000000000000000000000000000000000000000000000000008280520000000000000000000000000000000000000000000000000000000000000082905200000000000000000000000000000000000000000000000000000000000000830052000000000000000000000000000000000000000000000000000000000000008310520000000000000000000000000000000000000000000000000000000000000083205200000000000000000000000000000000000000000000000000000000000000833052000000000000000000000000000000000000000000000000000000000000008340520000000000000000000000000000000000000000000000000000000000000083505200000000000000000000000000000000000000000000000000000000000000836052000000000000000000000000000000000000000000000000000000000000008370520000000000000000000000000000000000000000000000000000000000000083805200000000000000000000000000000000000000000000000000000000000000839052000000000000000000000000000000000000000000000000000000000000008400520000000000000000000000000000000000000000000000000000000000000084105200000000000000000000000000000000000000000000000000000000000000842052000000000000000000000000000000000000000000000000000000000000008430520000000000000000000000000000000000000000000000000000000000000084405200000000000000000000000000000000000000000000000000000000000000845052000000000000000000000000000000000000000000000000000000000000008460520000000000000000000000000000000000000000000000000000000000000084705200000000000000000000000000000000000000000000000000000000000000848052000000000000000000000000000000000000000000000000000000000000008490520000000000000000000000000000000000000000000000000000000000000085005200000000000000000000000000000000000000000000000000000000000000851052000000000000000000000000000000000000000000000000000000000000008520520000000000000000000000000000000000000000000000000000000000000085305200000000000000000000000000000000000000000000000000000000000000854052000000000000000000000000000000000000000000000000000000000000008550520000000000000000000000000000000000000000000000000000000000000085605200000000000000000000000000000000000000000000000000000000000000857052000000000000000000000000000000000000000000000000000000000000008580520000000000000000000000000000000000000000000000000000000000000085905200000000000000000000000000000000000000000000000000000000000000860052000000000000000000000000000000000000000000000000000000000000008610520000000000000000000000000000000000000000000000000000000000000086205200000000000000000000000000000000000000000000000000000000000000863052000000000000000000000000000000000000000000000000000000000000008640520000000000000000000000000000000000000000000000000000000000000086505200000000000000000000000000000000000000000000000000000000000000866052000000000000000000000000000000000000000000000000000000000000008670520000000000000000000000000000000000000000000000000000000000000086805200000000000000000000000000000000000000000000000000000000000000869052000000000000000000000000000000000000000000000000000000000000008700520000000000000000000000000000000000000000000000000000000000000087105200000000000000000000000000000000000000000000000000000000000000872052000000000000000000000000000000000000000000000000000000000000008730520000000000000000000000000000000000000000000000000000000000000087405200000000000000000000000000000000000000000000000000000000000000875052000000000000000000000000000000000000000000000000000000000000008760520000000000000000000000000000000000000000000000000000000000000087705200000000000000000000000000000000000000000000000000000000000000878052000000000000000000000000000000000000000000000000000000000000008790520000000000000000000000000000000000000000000000000000000000000088005200000000000000000000000000000000000000000000000000000000000000881052000000000000000000000000000000000000000000000000000000000000008820520000000000000000000000000000000000000000000000000000000000000088305200000000000000000000000000000000000000000000000000000000000000884052000000000000000000000000000000000000000000000000000000000000008850520000000000000000000000000000000000000000000000000000000000000088605200000000000000000000000000000000000000000000000000000000000000887052000000000000000000000000000000000000000000000000000000000000008880520000000000000000000000000000000000000000000000000000000000000088905200000000000000000000000000000000000000000000000000000000000000890052000000000000000000000000000000000000000000000000000000000000008910520000000000000000000000000000000000000000000000000000000000000089205200000000000000000000000000000000000000000000000000000000000000893052000000000000000000000000000000000000000000000000000000000000008940520000000000000000000000000000000000000000000000000000000000000089505200000000000000000000000000000000000000000000000000000000000000896052000000000000000000000000000000000000000000000000000000000000008970520000000000000000000000000000000000000000000000000000000000000089805200000000000000000000000000000000000000000000000000000000000000899052000000000000000000000000000000000000000000000000000000000000009000520000000000000000000000000000000000000000000000000000000000000090105200000000000000000000000000000000000000000000000000000000000000902052000000000000000000000000000000000000000000000000000000000000009030520000000000000000000000000000000000000000000000000000000000000090405200000000000000000000000000000000000000000000000000000000000000905052000000000000000000000000000000000000000000000000000000000000009060520000000000000000000000000000000000000000000000000000000000000090705200000000000000000000000000000000000000000000000000000000000000908052000000000000000000000000000000000000000000000000000000000000009090520000000000000000000000000000000000000000000000000000000000000091005200000000000000000000000000000000000000000000000000000000000000911052000000000000000000000000000000000000000000000000000000000000009120520000000000000000000000000000000000000000000000000000000000000091305200000000000000000000000000000000000000000000000000000000000000914052000000000000000000000000000000000000000000000000000000000000009150520000000000000000000000000000000000000000000000000000000000000091605200000000000000000000000000000000000000000000000000000000000000917052000000000000000000000000000000000000000000000000000000000000009180520000000000000000000000000000000000000000000000000000000000000091905200000000000000000000000000000000000000000000000000000000000000920052000000000000000000000000000000000000000000000000000000000000009210520000000000000000000000000000000000000000000000000000000000000092205200000000000000000000000000000000000000000000000000000000000000923052000000000000000000000000000000000000000000000000000000000000009240520000000000000000000000000000000000000000000000000000000000000092505200000000000000000000000000000000000000000000000000000000000000926052000000000000000000000000000000000000000000000000000000000000009270520000000000000000000000000000000000000000000000000000000000000092805200000000000000000000000000000000000000000000000000000000000000929052000000000000000000000000000000000000000000000000000000000000009300520000000000000000000000000000000000000000000000000000000000000093105200000000000000000000000000000000000000000000000000000000000000932052000000000000000000000000000000000000000000000000000000000000009330520000000000000000000000000000000000000000000000000000000000000093405200000000000000000000000000000000000000000000000000000000000000935052000000000000000000000000000000000000000000000000000000000000009360520000000000000000000000000000000000000000000000000000000000000093705200000000000000000000000000000000000000000000000000000000000000938052000000000000000000000000000000000000000000000000000000000000009390520000000000000000000000000000000000000000000000000000000000000094005200000000000000000000000000000000000000000000000000000000000000941052000000000000000000000000000000000000000000000000000000000000009420520000000000000000000000000000000000000000000000000000000000000094305200000000000000000000000000000000000000000000000000000000000000944052000000000000000000000000000000000000000000000000000000000000009450520000000000000000000000000000000000000000000000000000000000000094605200000000000000000000000000000000000000000000000000000000000000947052000000000000000000000000000000000000000000000000000000000000009480520000000000000000000000000000000000000000000000000000000000000094905200000000000000000000000000000000000000000000000000000000000000950052000000000000000000000000000000000000000000000000000000000000009510520000000000000000000000000000000000000000000000000000000000000095205200000000000000000000000000000000000000000000000000000000000000953052000000000000000000000000000000000000000000000000000000000000009540520000000000000000000000000000000000000000000000000000000000000095505200000000000000000000000000000000000000000000000000000000000000956052000000000000000000000000000000000000000000000000000000000000009570520000000000000000000000000000000000000000000000000000000000000095805200000000000000000000000000000000000000000000000000000000000000959052000000000000000000000000000000000000000000000000000000000000009600520000000000000000000000000000000000000000000000000000000000000096105200000000000000000000000000000000000000000000000000000000000000962052000000000000000000000000000000000000000000000000000000000000009630520000000000000000000000000000000000000000000000000000000000000096405200000000000000000000000000000000000000000000000000000000000000965052000000000000000000000000000000000000000000000000000000000000009660520000000000000000000000000000000000000000000000000000000000000096705200000000000000000000000000000000000000000000000000000000000000968052000000000000000000000000000000000000000000000000000000000000009690520000000000000000000000000000000000000000000000000000000000000097005200000000000000000000000000000000000000000000000000000000000000971052000000000000000000000000000000000000000000000000000000000000009720520000000000000000000000000000000000000000000000000000000000000097305200000000000000000000000000000000000000000000000000000000000000974052000000000000000000000000000000000000000000000000000000000000009750520000000000000000000000000000000000000000000000000000000000000097605200000000000000000000000000000000000000000000000000000000000000977052000000000000000000000000000000000000000000000000000000000000009780520000000000000000000000000000000000000000000000000000000000000097905200000000000000000000000000000000000000000000000000000000000000980052000000000000000000000000000000000000000000000000000000000000009810520000000000000000000000000000000000000000000000000000000000000098205200000000000000000000000000000000000000000000000000000000000000983052000000000000000000000000000000000000000000000000000000000000009840520000000000000000000000000000000000000000000000000000000000000098505200000000000000000000000000000000000000000000000000000000000000986052000000000000000000000000000000000000000000000000000000000000009870520000000000000000000000000000000000000000000000000000000000000098805200000000000000000000000000000000000000000000000000000000000000989052000000000000000000000000000000000000000000000000000000000000009900520000000000000000000000000000000000000000000000000000000000000099105200000000000000000000000000000000000000000000000000000000000000992052000000000000000000000000000000000000000000000000000000000000009930520000000000000000000000000000000000000000000000000000000000000099405200000000000000000000000000000000000000000000000000000000000000995052000000000000000000000000000000000000000000000000000000000000009960520000000000000000000000000000000000000000000000000000000000000099705200000000000000000000000000000000000000000000000000000000000000998052000000000000000000000000000000000000000000000000000000000000009990520e57eb8d10b6eed36a88a464538f8fcedbba7b1a71d6ed52124f77b835807d0fd05201c53ca351e7f26f963ced56cf18f9ebee56535170171b72a0addb4e1613776850520636b8e5a599cfe0833dbe141dbc093d65e0a497451ac21415fbf03698587c7b905204ea21cad94a85adb252b0a76b9826c67d7c697ca386d201752e38f19ed92a223126170746f733a3a6d657461646174615f7630c201032003000000000000134552525f414c52454144595f50524553454e542c4164647265737320697320616c72656164792070726573656e7420696e207468652077686974656c6973742e2103000000000000134552525f4e4f5f535543485f41444452455353214e6f2073756368206164647265737320696e207468652077686974656c6973742e2203000000000000134552525f4e4f545f494e495449414c495a45441d57686974656c697374206973206e6f7420696e697469616c697a65642e000201090b010205020001040100051d0b0011050c020b02070321030907012707032900030e0701270a01110220031407002707032a000c030b030f000b013101380002010104010008b01f0b0011050c010b01070321030907012707032a000c030b030f000c020a020704310138000a020705310138000a020706310138000a020707310138000a020708310138000a020709310138000a02070a310138000a02070b310138000a02070c310138000a02070d310138000a02070e310138000a02070f310138000a020710310138000a020711310138000a020712310138000a020713310138000a020714310138000a020715310138000a020716310138000a020717310138000a020718310138000a020719310138000a02071a310138000a02071b310138000a02071c310138000a02071d310138000a02071e310138000a02071f310138000a020720310138000a020721310138000a020722310138000a020723310138000a020724310138000a020725310138000a020726310138000a020727310138000a020728310138000a020729310138000a02072a310138000a02072b310138000a02072c310138000a02072d310138000a02072e310138000a02072f310138000a020730310138000a020731310138000a020732310138000a020733310138000a020734310138000a020735310138000a020736310138000a020737310138000a020738310138000a020739310138000a02073a310138000a02073b310138000a02073c310138000a02073d310138000a02073e310138000a02073f310138000a020740310138000a020741310138000a020742310138000a020743310138000a020744310138000a020745310138000a020746310138000a020747310138000a020748310138000a020749310138000a02074a310138000a02074b310138000a02074c310138000a02074d310138000a02074e310138000a02074f310138000a020750310138000a020751310138000a020752310138000a020753310138000a020754310138000a020755310138000a020756310138000a020757310138000a020758310138000a020759310138000a02075a310138000a02075b310138000a02075c310138000a02075d310138000a02075e310138000a02075f310138000a020760310138000a020761310138000a020762310138000a020763310138000a020764310138000a020765310138000a020766310138000a020767310138000a020768310138000a020769310138000a02076a310138000a02076b310138000a02076c310138000a02076d310138000a02076e310138000a02076f310138000a020770310138000a020771310138000a020772310138000a020773310138000a020774310138000a020775310138000a020776310138000a020777310138000a020778310138000a020779310138000a02077a310138000a02077b310138000a02077c310138000a02077d310138000a02077e310138000a02077f310138000a02078001310138000a02078101310138000a02078201310138000a02078301310138000a02078401310138000a02078501310138000a02078601310138000a02078701310138000a02078801310138000a02078901310138000a02078a01310138000a02078b01310138000a02078c01310138000a02078d01310138000a02078e01310138000a02078f01310138000a02079001310138000a02079101310138000a02079201310138000a02079301310138000a02079401310138000a02079501310138000a02079601310138000a02079701310138000a02079801310138000a02079901310138000a02079a01310138000a02079b01310138000a02079c01310138000a02079d01310138000a02079e01310138000a02079f01310138000a0207a001310138000a0207a101310138000a0207a201310138000a0207a301310138000a0207a401310138000a0207a501310138000a0207a601310138000a0207a701310138000a0207a801310138000a0207a901310138000a0207aa01310138000a0207ab01310138000a0207ac01310138000a0207ad01310138000a0207ae01310138000a0207af01310138000a0207b001310138000a0207b101310138000a0207b201310138000a0207b301310138000a0207b401310138000a0207b501310138000a0207b601310138000a0207b701310138000a0207b801310138000a0207b901310138000a0207ba01310138000a0207bb01310138000a0207bc01310138000a0207bd01310138000a0207be01310138000a0207bf01310138000a0207c001310138000a0207c101310138000a0207c201310138000a0207c301310138000a0207c401310138000a0207c501310138000a0207c601310138000a0207c701310138000a0207c801310138000a0207c901310138000a0207ca01310138000a0207cb01310138000a0207cc01310138000a0207cd01310138000a0207ce01310138000a0207cf01310138000a0207d001310138000a0207d101310138000a0207d201310138000a0207d301310138000a0207d401310138000a0207d501310138000a0207d601310138000a0207d701310138000a0207d801310138000a0207d901310138000a0207da01310138000a0207db01310138000a0207dc01310138000a0207dd01310138000a0207de01310138000a0207df01310138000a0207e001310138000a0207e101310138000a0207e201310138000a0207e301310138000a0207e401310138000a0207e501310138000a0207e601310138000a0207e701310138000a0207e801310138000a0207e901310138000a0207ea01310138000a0207eb01310138000a0207ec01310138000a0207ed01310138000a0207ee01310138000a0207ef01310138000a0207f001310138000a0207f101310138000a0207f201310138000a0207f301310138000a0207f401310138000a0207f501310138000a0207f601310138000a0207f701310138000a0207f801310138000a0207f901310138000a0207fa01310138000a0207fb01310138000a0207fc01310138000a0207fd01310138000a0207fe01310138000a0207ff01310138000a02078002310138000a02078102310138000a02078202310138000a02078302310138000a02078402310138000a02078502310138000a02078602310138000a02078702310138000a02078802310138000a02078902310138000a02078a02310138000a02078b02310138000a02078c02310138000a02078d02310138000a02078e02310138000a02078f02310138000a02079002310138000a02079102310138000a02079202310138000a02079302310138000a02079402310138000a02079502310138000a02079602310138000a02079702310138000a02079802310138000a02079902310138000a02079a02310138000a02079b02310138000a02079c02310138000a02079d02310138000a02079e02310138000a02079f02310138000a0207a002310138000a0207a102310138000a0207a202310138000a0207a302310138000a0207a402310138000a0207a502310138000a0207a602310138000a0207a702310138000a0207a802310138000a0207a902310138000a0207aa02310138000a0207ab02310138000a0207ac02310138000a0207ad02310138000a0207ae02310138000a0207af02310138000a0207b002310138000a0207b102310138000a0207b202310138000a0207b302310138000a0207b402310138000a0207b502310138000a0207b602310138000a0207b702310138000a0207b802310138000a0207b902310138000a0207ba02310138000a0207bb02310138000a0207bc02310138000a0207bd02310138000a0207be02310138000a0207bf02310138000a0207c002310138000a0207c102310138000a0207c202310138000a0207c302310138000a0207c402310138000a0207c502310138000a0207c602310138000a0207c702310138000a0207c802310138000a0207c902310138000a0207ca02310138000a0207cb02310138000a0207cc02310138000a0207cd02310138000a0207ce02310138000a0207cf02310138000a0207d002310138000a0207d102310138000a0207d202310138000a0207d302310138000a0207d402310138000a0207d502310138000a0207d602310138000a0207d702310138000a0207d802310138000a0207d902310138000a0207da02310138000a0207db02310138000a0207dc02310138000a0207dd02310138000a0207de02310138000a0207df02310138000a0207e002310138000a0207e102310138000a0207e202310138000a0207e302310138000a0207e402310138000a0207e502310138000a0207e602310138000a0207e702310138000a0207e802310138000a0207e902310138000a0207ea02310138000a0207eb02310138000a0207ec02310138000a0207ed02310138000a0207ee02310138000a0207ef02310138000a0207f002310138000a0207f102310138000a0207f202310138000a0207f302310138000a0207f402310138000a0207f502310138000a0207f602310138000a0207f702310138000a0207f802310138000a0207f902310138000a0207fa02310138000a0207fb02310138000a0207fc02310138000a0207fd02310138000a0207fe02310138000a0207ff02310138000a02078003310138000a02078103310138000a02078203310138000a02078303310138000a02078403310138000a02078503310138000a02078603310138000a02078703310138000a02078803310138000a02078903310138000a02078a03310138000a02078b03310138000a02078c03310138000a02078d03310138000a02078e03310138000a02078f03310138000a02079003310138000a02079103310138000a02079203310138000a02079303310138000a02079403310138000a02079503310138000a02079603310138000a02079703310138000a02079803310138000a02079903310138000a02079a03310138000a02079b03310138000a02079c03310138000a02079d03310138000a02079e03310138000a02079f03310138000a0207a003310138000a0207a103310138000a0207a203310138000a0207a303310138000a0207a403310138000a0207a503310138000a0207a603310138000a0207a703310138000a0207a803310138000a0207a903310138000a0207aa03310138000a0207ab03310138000a0207ac03310138000a0207ad03310138000a0207ae03310138000a0207af03310138000a0207b003310138000a0207b103310138000a0207b203310138000a0207b303310138000a0207b403310138000a0207b503310138000a0207b603310138000a0207b703310138000a0207b803310138000a0207b903310138000a0207ba03310138000a0207bb03310138000a0207bc03310138000a0207bd03310138000a0207be03310138000a0207bf03310138000a0207c003310138000a0207c103310138000a0207c203310138000a0207c303310138000a0207c403310138000a0207c503310138000a0207c603310138000a0207c703310138000a0207c803310138000a0207c903310138000a0207ca03310138000a0207cb03310138000a0207cc03310138000a0207cd03310138000a0207ce03310138000a0207cf03310138000a0207d003310138000a0207d103310138000a0207d203310138000a0207d303310138000a0207d403310138000a0207d503310138000a0207d603310138000a0207d703310138000a0207d803310138000a0207d903310138000a0207da03310138000a0207db03310138000a0207dc03310138000a0207dd03310138000a0207de03310138000a0207df03310138000a0207e003310138000a0207e103310138000a0207e203310138000a0207e303310138000a0207e403310138000a0207e503310138000a0207e603310138000a0207e703310138000a0207e803310138000a0207e903310138000a0207ea03310138000a0207eb03310138000a0207ec03310138000a0207ed03310138000a0207ee03310138000a0207ef03310138000a0207f003310138000a0207f103310138000a0207f203310138000a0207f303310138000a0207f403310138000a0207f503310138000a0207f603310138000a0207f703310138000a0207f803310138000a0207f903310138000a0207fa03310138000a0207fb03310138000a0207fc03310138000a0207fd03310138000a0207fe03310138000a0207ff03310138000a02078004310138000a02078104310138000a02078204310138000a02078304310138000a02078404310138000a02078504310138000a02078604310138000a02078704310138000a02078804310138000a02078904310138000a02078a04310138000a02078b04310138000a02078c04310138000a02078d04310138000a02078e04310138000a02078f04310138000a02079004310138000a02079104310138000a02079204310138000a02079304310138000a02079404310138000a02079504310138000a02079604310138000a02079704310138000a02079804310138000a02079904310138000a02079a04310138000a02079b04310138000a02079c04310138000a02079d04310138000a02079e04310138000a02079f04310138000a0207a004310138000a0207a104310138000a0207a204310138000a0207a304310138000a0207a404310138000a0207a504310138000a0207a604310138000a0207a704310138000a0207a804310138000a0207a904310138000a0207aa04310138000a0207ab04310138000a0207ac04310138000a0207ad04310138000a0207ae04310138000a0207af04310138000a0207b004310138000a0207b104310138000a0207b204310138000a0207b304310138000a0207b404310138000a0207b504310138000a0207b604310138000a0207b704310138000a0207b804310138000a0207b904310138000a0207ba04310138000a0207bb04310138000a0207bc04310138000a0207bd04310138000a0207be04310138000a0207bf04310138000a0207c004310138000a0207c104310138000a0207c204310138000a0207c304310138000a0207c404310138000a0207c504310138000a0207c604310138000a0207c704310138000a0207c804310138000a0207c904310138000a0207ca04310138000a0207cb04310138000a0207cc04310138000a0207cd04310138000a0207ce04310138000a0207cf04310138000a0207d004310138000a0207d104310138000a0207d204310138000a0207d304310138000a0207d404310138000a0207d504310138000a0207d604310138000a0207d704310138000a0207d804310138000a0207d904310138000a0207da04310138000a0207db04310138000a0207dc04310138000a0207dd04310138000a0207de04310138000a0207df04310138000a0207e004310138000a0207e104310138000a0207e204310138000a0207e304310138000a0207e404310138000a0207e504310138000a0207e604310138000a0207e704310138000a0207e804310138000a0207e904310138000a0207ea04310138000a0207eb04310138000a0207ec04310138000a0207ed04310138000a0207ee04310138000a0207ef04310138000a0207f004310138000a0207f104310138000a0207f204310138000a0207f304310138000a0207f404310138000a0207f504310138000a0207f604310138000a0207f704310138000a0207f804310138000a0207f904310138000a0207fa04310138000a0207fb04310138000a0207fc04310138000a0207fd04310138000a0207fe04310138000a0207ff04310138000a02078005310138000a02078105310138000a02078205310138000a02078305310138000a02078405310138000a02078505310138000a02078605310138000a02078705310138000a02078805310138000a02078905310138000a02078a05310138000a02078b05310138000a02078c05310138000a02078d05310138000a02078e05310138000a02078f05310138000a02079005310138000a02079105310138000a02079205310138000a02079305310138000a02079405310138000a02079505310138000a02079605310138000a02079705310138000a02079805310138000a02079905310138000a02079a05310138000a02079b05310138000a02079c05310138000a02079d05310138000a02079e05310138000a02079f05310138000a0207a005310138000a0207a105310138000a0207a205310138000a0207a305310138000a0207a405310138000a0207a505310138000a0207a605310138000a0207a705310138000a0207a805310138000a0207a905310138000a0207aa05310138000a0207ab05310138000a0207ac05310138000a0207ad05310138000a0207ae05310138000a0207af05310138000a0207b005310138000a0207b105310138000a0207b205310138000a0207b305310138000a0207b405310138000a0207b505310138000a0207b605310138000a0207b705310138000a0207b805310138000a0207b905310138000a0207ba05310138000a0207bb05310138000a0207bc05310138000a0207bd05310138000a0207be05310138000a0207bf05310138000a0207c005310138000a0207c105310138000a0207c205310138000a0207c305310138000a0207c405310138000a0207c505310138000a0207c605310138000a0207c705310138000a0207c805310138000a0207c905310138000a0207ca05310138000a0207cb05310138000a0207cc05310138000a0207cd05310138000a0207ce05310138000a0207cf05310138000a0207d005310138000a0207d105310138000a0207d205310138000a0207d305310138000a0207d405310138000a0207d505310138000a0207d605310138000a0207d705310138000a0207d805310138000a0207d905310138000a0207da05310138000a0207db05310138000a0207dc05310138000a0207dd05310138000a0207de05310138000a0207df05310138000a0207e005310138000a0207e105310138000a0207e205310138000a0207e305310138000a0207e405310138000a0207e505310138000a0207e605310138000a0207e705310138000a0207e805310138000a0207e905310138000a0207ea05310138000a0207eb05310138000a0207ec05310138000a0207ed05310138000a0207ee05310138000a0207ef05310138000a0207f005310138000a0207f105310138000a0207f205310138000a0207f305310138000a0207f405310138000a0207f505310138000a0207f605310138000a0207f705310138000a0207f805310138000a0207f905310138000a0207fa05310138000a0207fb05310138000a0207fc05310138000a0207fd05310138000a0207fe05310138000a0207ff05310138000a02078006310138000a02078106310138000a02078206310138000a02078306310138000a02078406310138000a02078506310138000a02078606310138000a02078706310138000a02078806310138000a02078906310138000a02078a06310138000a02078b06310138000a02078c06310138000a02078d06310138000a02078e06310138000a02078f06310138000a02079006310138000a02079106310138000a02079206310138000a02079306310138000a02079406310138000a02079506310138000a02079606310138000a02079706310138000a02079806310138000a02079906310138000a02079a06310138000a02079b06310138000a02079c06310138000a02079d06310138000a02079e06310138000a02079f06310138000a0207a006310138000a0207a106310138000a0207a206310138000a0207a306310138000a0207a406310138000a0207a506310138000a0207a606310138000a0207a706310138000a0207a806310138000a0207a906310138000a0207aa06310138000a0207ab06310138000a0207ac06310138000a0207ad06310138000a0207ae06310138000a0207af06310138000a0207b006310138000a0207b106310138000a0207b206310138000a0207b306310138000a0207b406310138000a0207b506310138000a0207b606310138000a0207b706310138000a0207b806310138000a0207b906310138000a0207ba06310138000a0207bb06310138000a0207bc06310138000a0207bd06310138000a0207be06310138000a0207bf06310138000a0207c006310138000a0207c106310138000a0207c206310138000a0207c306310138000a0207c406310138000a0207c506310138000a0207c606310138000a0207c706310138000a0207c806310138000a0207c906310138000a0207ca06310138000a0207cb06310138000a0207cc06310138000a0207cd06310138000a0207ce06310138000a0207cf06310138000a0207d006310138000a0207d106310138000a0207d206310138000a0207d306310138000a0207d406310138000a0207d506310138000a0207d606310138000a0207d706310138000a0207d806310138000a0207d906310138000a0207da06310138000a0207db06310138000a0207dc06310138000a0207dd06310138000a0207de06310138000a0207df06310138000a0207e006310138000a0207e106310138000a0207e206310138000a0207e306310138000a0207e406310138000a0207e506310138000a0207e606310138000a0207e706310138000a0207e806310138000a0207e906310138000a0207ea06310138000a0207eb06310138000a0207ec06310138000a0207ed06310138000a0207ee06310138000a0207ef06310138000a0207f006310138000a0207f106310138000a0207f206310138000a0207f306310138000a0207f406310138000a0207f506310138000a0207f606310138000a0207f706310138000a0207f806310138000a0207f906310138000a0207fa06310138000a0207fb06310138000a0207fc06310138000a0207fd06310138000a0207fe06310138000a0207ff06310138000a02078007310138000a02078107310138000a02078207310138000a02078307310138000a02078407310138000a02078507310138000a02078607310138000a02078707310138000a02078807310138000a02078907310138000a02078a07310138000a02078b07310138000a02078c07310138000a02078d07310138000a02078e07310138000a02078f07310138000a02079007310138000a02079107310138000a02079207310138000a02079307310138000a02079407310138000a02079507310138000a02079607310138000a02079707310138000a02079807310138000a02079907310138000a02079a07310138000a02079b07310138000a02079c07310138000a02079d07310138000a02079e07310138000a02079f07310138000a0207a007310138000a0207a107310138000a0207a207310138000a0207a307310138000a0207a407310138000a0207a507310138000a0207a607310138000a0207a707310138000a0207a807310138000a0207a907310138000a0207aa07310138000a0207ab07310138000a0207ac07310138000a0207ad07310138000a0207ae07310138000a0207af07310138000a0207b007310138000a0207b107310138000a0207b207310138000a0207b307310138000a0207b407310138000a0207b507310138000a0207b607310138000a0207b707310138000a0207b807310138000a0207b907310138000a0207ba07310138000a0207bb07310138000a0207bc07310138000a0207bd07310138000a0207be07310138000a0207bf07310138000a0207c007310138000a0207c107310138000a0207c207310138000a0207c307310138000a0207c407310138000a0207c507310138000a0207c607310138000a0207c707310138000a0207c807310138000a0207c907310138000a0207ca07310138000a0207cb07310138000a0207cc07310138000a0207cd07310138000a0207ce07310138000a0207cf07310138000a0207d007310138000a0207d107310138000a0207d207310138000a0207d307310138000a0207d407310138000a0207d507310138000a0207d607310138000a0207d707310138000a0207d807310138000a0207d907310138000a0207da07310138000a0207db07310138000a0207dc07310138000a0207dd07310138000a0207de07310138000a0207df07310138000a0207e007310138000a0207e107310138000a0207e207310138000a0207e307310138000a0207e407310138000a0207e507310138000a0207e607310138000a0207e707310138000a0207e807310138000a0207e907310138000a0207ea07310138000b0207eb0731013800020201000100090807032b000c010b0110000b00380102030100000b1f38020c010d0107ec07310138000d0107ed07310138000d0107ee07310138000d0107ef07310138000d01071a310138000d01071b310138000b000b0112002d00020401040100051c0b0011050c020b02070321030907012707032900030e0701270a011102031307022707032a000c030b030f000b0138030102000000"; + let res = run_binary_test("sample_whitelist", code); + assert!(res.is_ok(), "{:?}", res) +} + +#[test] +fn sample_coin_store() { + let code = "a11ceb0b050000000e01001e021e0c032acb0604f5065405c907a41207ed19e80908d523800206d5252c108126420ac326090bcc26040cd026fd86010dcdad01020ecfad01040000010101020103020402050306030704080509050a0607060b070c070d000e08010001011104010001000f00010200000010010201000012030101000013040103000000001404010300000000150401030000000016040103000000001704010300000000180401030000000019040103000000001a040103000000001b040103000000001c040103000000001d040103000000001e040103000000001f0401030000000020040103000000002104010300000000220401030000000023040103000000002404010300000000250401030000000026040103000000002704010300000000280401030000000029040103000000002a040103000000002b040103000000002c040103000000002d040103000000002e040103000000002f0401030000000030040103000000003104010300000000320401030000000033050103000000003405010300000000350501030000000036050103000000003705010300000000380501030000000039050103000000003a050103000000003b050103000000003c050103000000003d050103000000003e050103000000003f0501030000000040050103000000004105010300000000420501030000000043050103000000004405010300000000450501030000000046050103000000004705010300000000480501030000000049050103000000004a050103000000004b050103000000004c050103000000004d050103000000004e050103000000004f050103000000005005010300000000510601010000520701010000530801010000540901020000005509010200000056000102000000570a010200000058070102000000590a01020000005a0b01020000005b0001020000005c0c0103000000005d0c01020000005e0c01020000005f0701010000600701010000610201010000620701010000630d01010000640e010100006502030100006601030100006702030100016810020100016911010100096a0114020000046b0100020000016c16030100016d01030100090b1819020000040b1a1b020000016e030101000c6f011d0200000b70031e020000066b0100030000000771221e030000000872010202000008730102020000087424000200000e6a01140200000d0b261e020000037508400002760202000165070301000477014200057801430200000a790100020000060b1a1b03000000011226010100017a48030100580f590f5a135a155b135c0f5d175e135e1559175d0f5f155f136017611361156215600f6320632164216513661366156515671568136815691562136420671369136c0f6e136f135c17702070215817710f720f020303000103010b010109000d030403040404010101010404040d0304030404010101010404040402060c0b0101090002060c0301060c0b030403040404010104040403060c030304060c0303010a060c03040403030404010102050303060c050301090001060b0101090002070b010109000b01010900230b010109000b010109010403040b010109000403040404040b010109010403030304040b010109000b010109000b01010901070b00010900040404040b010109000b010109000b0101090104040b0101090104040209000901020404020901090002070b0101090003010901040b01010900040b0101090104040b010109000b010109010b010109000b01010901040b01010900030b0101090103020b010109000b01010901250303030403040b010109000403040404040b0101090103030304040b010109000b010109010b01010900070b000109000404040b010109000b0101090003040404030b0101090104030403030303010b0101090122040303040b010109000403040404040b0101090103030304040b010109000b010109000b01010901070b000109000404040b0101090003040b010109000404030b0101090104040309000901090203090109000902020b010109000323040404040b010109000403040404040b0101090103030304040b010109000b010109000b01010901070b000109000404050b01010900040b010109000b01010901040b0101090004040b0101090104040805070b01010900070b01010901030301040423040404040b010109000403040404040b0101090103030304040b010109000b010109010b01010900070b00010900040405040b0101090004040b010109000404040b01010901040402050b01010900240403040403040404040403030304040b010109000b010109010b01010900070b000109000b0101090104040504040b010109010b010109000b01010900040b01010900040b010109010b0101090104040b01010900200303030403030404030404040403030304040b010109000b010109010b01010900070b000109000b010109010404030b01010900040303040b010109001d040303030404030404040403030304040b010109000b010109010b01010900070b000109000b01010901040403040b0101090003040b010109001e040404030404030404040403030304040b010109000b010109010b01010900070b000109000b010109010404050b01010900040b010109000b01010901040b010109001e040404030404030404040403030304040b010109000b010109010b01010900070b000109000b0101090104040504040b0101090004040b010109002603030304030403040404040403030304040b010109010b01010900070b00010900040405030b010109000b0101090104040b01010900040b01010900030b01010901040b01010901040304200303030b010109000b010109010403030403040404040403030304040b010109010b01010900070b000109000404030b010109000b01010901040303041d0303030403030304030404040403030304040b01010900070b0001090004040303040303030421030303040404030404030404040403030304040b010109010b01010900070b000109000404050b01010900030b010109000b01010901040303041f0303030404040304030404040403030304040b010109010b01010900070b0001090004040503040403040304230403030403040404040403030304040b010109000b01010901070b0001090004040503040b01010901040b010109000b01010900040b01010900030b01010901040b0101090104041d0b010109000b01010901040303030403040404040403030304040b010109000b01010901070b00010900040403040b010109000b0101090103041e04040403030404030404040403030304040b010109000b01010901070b000109000404050b0101090003040b010109000b0101090103041c040404030304030404040403030304040b010109000b01010901070b00010900040405030404030404240404040403040404040403030304040b010109000b010109000b01010901070b000109000404050b01010901040b01010901040b010109010b010109000b01010900040b01010900040b010109010b0101090104041f04040b010109000b0101090104030403040404040403030304040b010109000b010109000b01010901070b000109000404050b01010901040b010109010b010109000b0101090104200404030303040304030404040403030304040b010109000b01010900070b000109000404050b01010901030b010109010b01010900040303041d040404030304030404040403030304040b010109000b01010900070b000109000404050b0101090103040b010109010b0101090003041e040404040404030404040403030304040b010109000b010109010b01010900070b000109000404050b01010901040b01010900040b010109010404240404040403040404040403030304040b010109000b010109000b01010901070b00010900040405040b010109000b0101090104040b01010900040b01010900040b01010901040b0101090104041f04040b010109000b0101090104030403040404040403030304040b010109000b010109000b01010901070b0001090004040504040b010109000b0101090104041f0404030303040304030404040403030304040b010109000b01010900070b00010900040405040304040303041c040404030304030404040403030304040b010109000b01010900070b000109000404050403040403041f04040404040404030404040403030304040b010109000b010109000b01010901070b000109000404050b01010900040b010109000b01010901040404010b0001090001050d05030403070b000109000b01010901040b01010900040303030b01010900040302010101011a0504040404070b00010900070b000109010404030303030b01010901040404040b010109000b010109000b010109000b010109000b010109010b010109010b010109010b010109010f03030305040404030b010109010b01010901040b0101090003030b010109000e04040305040404030b010109000b01010901040b010109010b010109010b010109000f030303030305040404030b010109010403030301070b01010900030b0101090003070b000109000a636f696e5f73746f726504636f696e056572726f72067369676e65720f416e696d6553776170506f6f6c563116416e696d6553776170506f6f6c56314c6962726172790e6c69717569646974795f706f6f6c06726f7574657203616d6d09546f6b656e537761700f546f6b656e53776170436f6e66696704737761700a616d6d5f726f7574657208616d6d5f737761700b4d79436f696e53746f726512616e696d65737761705f73746172737761700762616c616e636504436f696e076465706f736974066c3073307431066c3073317430066c3173307431066c3173307432066c3173307433066c3173307434066c3173307435066c3173317430066c3173317432066c3173317433066c3173317434066c3173317435066c3173327430066c3173327431066c3173327433066c3173327434066c3173327435066c3173337430066c3173337431066c3173337432066c3173337434066c3173337435066c3173347430066c3173347431066c3173347432066c3173347433066c3173347435066c3173357430066c3173357431066c3173357432066c3173357433066c3173357434066c3273307431066c3273307432066c3273307433066c3273307434066c3273307435066c3273317430066c3273317432066c3273317433066c3273317434066c3273317435066c3273327430066c3273327431066c3273327433066c3273327434066c3273327435066c3273337430066c3273337431066c3273337432066c3273337434066c3273337435066c3273347430066c3273347431066c3273347432066c3273347433066c3273347435066c3273357430066c3273357431066c3273357432066c3273357433066c3273357434036e65770d6e65775f66726f6d5f6d61696e0d6e65775f66726f6d5f7a65726f047330743104733174301073696d706c655f616e696d65737761701373696d706c655f616e696d65737761705f76320f73696d706c655f73746172737761701273696d706c655f73746172737761705f76321273696d706c655f73746172737761705f76331273746172737761705f616e696d657377617012737761705f61625f6c69717569647377617008737761705f61757810737761705f70616e63616b6573776170127472616e736665725f66726f6d5f6d61696e197472616e736665725f66726f6d5f6d61696e5f736372697074107472616e736665725f746f5f6d61696e177472616e736665725f746f5f6d61696e5f736372697074117472616e736665725f746f5f6f74686572187472616e736665725f746f5f6f746865725f7363726970740877697468647261770c77697468647261775f616c6c0c77697468647261775f616e790576616c7565056d657267650c6765745f7265736572766573116765745f72657365727665735f73697a650765787472616374047a65726f0c64657374726f795f7a65726f0e746f6b656e5f726573657276657321737761705f65786163745f785f746f5f795f6469726563745f65787465726e616c18737761705f65786163745f636f696e5f666f725f636f696e04785f617504795f61751c737761705f65786163745f636f696e5f666f725f636f696e5f6d75740a616464726573735f6f66117065726d697373696f6e5f64656e6965640e6765745f61646d696e5f6461746107636f6d70617265116765745f706f756e646167655f726174650b657874726163745f616c6cd1b58e44ea11ffd326a280c453b080fd8af294298815a00e65b6e2bffc48d6ac000000000000000000000000000000000000000000000000000000000000000116fe2df00ea7dde4a63409201f7f4e536bde7bb7335526a35d05111e68aa322c190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12bd35135844473187163ca197ca93b2ab014370587bb0ed3befff9e902d6bb541c755e4c8d7a6ab6d56f9289d97c43c1c94bde75ec09147c90d35cd1be61c8fb9c7efb4076dbe143cbcd98cfaaa929ecfc8f299203dfff63b95ccb6bfe19850faec42a352cc65eca17a9fa85d0fc602295897ed6b8b8af6a6c79ef490eb8f9eba0308915f0100000000000520d1b58e44ea11ffd326a280c453b080fd8af294298815a00e65b6e2bffc48d6ac126170746f733a3a6d657461646174615f76302e01915f010000000000234552524f525f5448455f4f55545055545f4c4553535f5448414e5f4d494e5f5245435600000201010b01010900000f001700010400010206ffffffffffffffff270101000100010507013c0037003800020201000100010607013c0036000b0038010203010400010206ffffffffffffffff2704010400010206ffffffffffffffff2705010400010206ffffffffffffffff2706010400010206ffffffffffffffff2707010400010206ffffffffffffffff2708010400010206ffffffffffffffff2709010400010206ffffffffffffffff270a010400010206ffffffffffffffff270b010400010206ffffffffffffffff270c010400010206ffffffffffffffff270d010400010206ffffffffffffffff270e010400010206ffffffffffffffff270f010400010206ffffffffffffffff2710010400010206ffffffffffffffff2711010400010206ffffffffffffffff2712010400010206ffffffffffffffff2713010400010206ffffffffffffffff2714010400010206ffffffffffffffff2715010400010206ffffffffffffffff2716010400010206ffffffffffffffff2717010400010206ffffffffffffffff2718010400010206ffffffffffffffff2719010400010206ffffffffffffffff271a010400010206ffffffffffffffff271b010400010206ffffffffffffffff271c010400010206ffffffffffffffff271d010400010206ffffffffffffffff271e010400010206ffffffffffffffff271f010400010206ffffffffffffffff2720010400010206ffffffffffffffff2721010400010206ffffffffffffffff2722010400010206ffffffffffffffff27230104010012f1010b05040638020c2c0c26050d38030c2b0c2e0b2b0c260b2e0c2c0b260b2c0c180c1738040c10350b10350c1f0c1e0a0432000000000000000000000000000000002104660a180a0c180a0a1a0a1f160c110a170a1f180a111a0c0f0a1e0a18180a0c180a0a1a0b111a0c110a0f0a11180a0b180a091a0c2f0a0f0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2f23045e054d0a270c2f0a0f0a11180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705480b2f0b0f170a0b180a091a0c040a040b0b180c150b170b09180a15160c240b150b18180b241a320b000000000000000000000000000000170c130a130b0c180c160b1f0b0a180a16160c250b160b1e180b251a320b000000000000000000000000000000170c1a0a1a0a04170b0317010b04340c1407013c000c230a23370038000c1b0a2336000b1438050c200b0804ab010b200b133806320000000000000000000000000000000038070c190c120c2d0c2805b401380632000000000000000000000000000000000b200b1338080c120c190c280c2d0d280b1238010d2d0b1938090b2d0c220a2336000b283801380a0c290b0704cd010b220600000000000000000b290b1a34380b0c0d0c0e05d5010b290b1a340b22060000000000000000380c0c0e0c0d0b0e0b0d0c210c2a0a2336000b2138010b1b0b02160c1c0b23370038000c1d0a1d0a1c2404ea0105ee010b1c0b1d17270b2a380d0224010401001cef010b05040638020c2c0c26050d38030c2b0c2f0b2b0c260b2f0c2c0b260b2c0c190c180b060418380e0c0f0c0e0c0d0522380f0c300c290c2d0b290b2d0b300c0f0c0e0c0d0b0d0b0e0b0f010c11350b11350c1f0c1e0a04320000000000000000000000000000000021047a0a190a0c180a0a1a0a1f160c120a180a1f180a121a0c100a1e0a19180a0c180a0a1a0b121a0c120a100a12180a0b180a091a0c310a100a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c2a0a2a0a3123047205610a2a0c310a100a12180a0b180a091a0a2a1a0b2a1632020000000000000000000000000000001a0c2a055c0b310b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c240b160b19180b241a320b000000000000000000000000000000170c140a140b0c180c170b1f0b0a180a17160c250b170b1e180b251a320b000000000000000000000000000000170a04170b0317010b04340c1507013c000c230a23370038000c1b0a2336000b1538050c200b0804bd010b200b143806320000000000000000000000000000000038070c1a0c130c2e0c2705c601380632000000000000000000000000000000000b200b1438080c130c1a0c270c2e0d270b1338010d2e0b1a38090b2e0c210a2336000b273801380a0c280b2138100c220a2336000b2238010b1b0b02160c1c0b23370038000c1d0a1d0a1c2404e80105ec010b1c0b1d17270b2838110225010401001fe8010b05040638020c2a0c24050d38030c290c2d0b290c240b2d0c2a0b240b2a0c170c160b06041738120c0f0c0e051e38130c260c2b0b260c0e0b2b0c0f0b0e350b0f350c1d0c1c0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1d160c100a160a1d180a101a0c0d0a1c0a17180a0c180a0a1a0b101a0c100a0d0a10180a0b180a091a0c2e0a0d0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2e23046a05590a270c2e0a0d0a10180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705540b2e0b0d170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1d0b0a180a15160c230b150b1c180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307013c000c210a21370038000c190a2136000b1338050c1e0b0804b5010b1e0b123806320000000000000000000000000000000038070c180c110c2c0c2805be01380632000000000000000000000000000000000b1e0b1238080c110c180c280c2c0d280b1138010d2c0b1838090b2c0c200a2136000b283801380a0c250b2006000000000000000038140c1f0a2136000b1f38010b190b02160c1a0b21370038000c1b0a1b0a1a2404e10105e5010b1a0b1b17270b25381102260104010023f8010b05040638020c2c0c26050d38030c2b0c2e0b2b0c260b2e0c2c0b260b2c0c170c160b06041a3815353816350c0e0c0d05203817353818350c0e0c0d0b0d0b0e0c1d0c1c0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1d160c100a160a1d180a101a0c0f0a1c0a17180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c2f0a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2f23046a05590a290c2f0a0f0a10180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c2905540b2f0b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1d0b0a180a15160c230b150b1c180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c210a21370038000c190a2136000b1338050c1e0b0804b7010b1e0a123806320000000000000000000000000000000038070c180c110c2d0c2a05c001380632000000000000000000000000000000000b1e0a1238080c110c180c2a0c2d0d2a0b1138010d2d0b1838090b2d0c200a2136000b2a3801380a0c270b240d200d270b12340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c250b200c280b250c1f0a2136000b1f38010b190b02160c1a0b21370038000c1b0a1b0a1a2404f10105f5010b1a0b1b17270b28380d02270104010025e8010b05040638020c2b0c25050d38030c2a0c2e0b2a0c250b2e0c2b0b250b2b0c170c160b060417381a0c0e0c0d051e381b0c270c2c0b270b2c0c0e0c0d0b0d0b0e0c1d0c1c0a0432000000000000000000000000000000002104700a170a0c180a0a1a0a1d160c100a160a1d180a101a0c0f0a1c0a17180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c2f0a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c280a280a2f23046805570a280c2f0a0f0a10180a0b180a091a0a281a0b281632020000000000000000000000000000001a0c2805520b2f0b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1d0b0a180a15160c230b150b1c180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c210a21370038000c190a2136000b1338050c1e0b0804b5010b1e0b123806320000000000000000000000000000000038070c180c110c2d0c2905be01380632000000000000000000000000000000000b1e0b1238080c110c180c290c2d0d290b1138010d2d0b1838090b2d0c1f0a2136000b293801380a0c260b240b1f381c0c200a2136000b2038010b190b02160c1a0b21370038000c1b0a1b0a1a2404e10105e5010b1a0b1b17270b26381102280104010027f20138040c0e350b0e350c150c140b06040d38020c2b0c24051438030c290c2e0b290c240b2e0c2b0b240b2b0c1b0c1a0a0432000000000000000000000000000000002104660a150a0c180a0a1a0a1b160c0f0a140a1b180a0f1a0c0d0a1a0a15180a0c180a0a1a0b0f1a0c0f0a0d0a0f180a0b180a091a0c2f0a0d0a0f180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2f23045e054d0a250c2f0a0d0a0f180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505480b2f0b0d170a0b180a091a0c040a040b0b180c120b140b09180a12160c210b120b15180b211a320b000000000000000000000000000000170c100a100b0c180c130b1b0b0a180a13160c220b130b1a180b221a320b000000000000000000000000000000170c160a160a04170b0317010b04340c1107010c230a233c000c1f0a1f370038000c170a1f36000b1138050c1c0b0804ac010b1c06000000000000000038060b1034380c0c200c3005b40138060b10340b1c060000000000000000380b0c300c200b300b200c1d0c270b0704c4010b1d0b160b27320000000000000000000000000000000038080c280c2d0c2a0c2c05cd010b2732000000000000000000000000000000000b1d0b1638070c2d0c280c2c0c2a0d2a0b2838010d2c0b2d38090b2a0c1e0b2c0c260a1f36000b1e38010b170b02160c180b1f370038000c190a190a182404e80105ec010b180b1917270b233c0136010b26380902290104010028d90138040c11350b11350c190c180b06040e380e0c0f0c0e0c0d0518380f0c2a0c260c290b260b290b2a0c0f0c0e0c0d0b0d0b0e0b0f010c12350b12350c1e0c1d0a0432000000000000000000000000000000002104700a190a0c180a0a1a0a1e160c130a180a1e180a131a0c100a1d0a19180a0c180a0a1a0b131a0c130a100a13180a0b180a091a0c2b0a100a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c280a280a2b23046805570a280c2b0a100a13180a0b180a091a0a281a0b281632020000000000000000000000000000001a0c2805520b2b0b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c240b160b19180b241a320b000000000000000000000000000000170c140a140b0c180c170b1e0b0a180a17160c250b170b1d180b251a320b000000000000000000000000000000170a04170b0317010b04340c1507013c000c220a22370038000c1a0a2236000b1538050c1f0b0804b2010b1f06000000000000000038060b1434380c0c230c2c05ba0138060b14340b1f060000000000000000380b0c2c0c230b2c0b230c200c270b2038100c210a2236000b2138010b1a0b02160c1b0b22370038000c1c0a1c0a1b2404d20105d6010b1b0b1c17270b273811022a0104010029d20138040c0f350b0f350c170c160b06040d38120c100c0e051438130c240c270b240c0e0b270c100b0e350b10350c1c0c1b0a0432000000000000000000000000000000002104680a170a0c180a0a1a0a1c160c110a160a1c180a111a0c0d0a1b0a17180a0c180a0a1a0b111a0c110a0d0a11180a0b180a091a0c280a0d0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a28230460054f0a250c280a0d0a11180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25054a0b280b0d170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1c0b0a180a15160c230b150b1b180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307013c000c200a20370038000c180a2036000b1338050c1d0b0804aa010b1d06000000000000000038060b1234380c0c210c2905b20138060b12340b1d060000000000000000380b0c290c210b290b210c1e0c260b1e06000000000000000038140c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404cb0105cf010b190b1a17270b263811022b010401002ae20138040c10350b10350c170c160b0604103815353816350c0e0c0d05163817353818350c0e0c0d0b0d0b0e0c1c0c1b0a0432000000000000000000000000000000002104680a170a0c180a0a1a0a1c160c110a160a1c180a111a0c0f0a1b0a17180a0c180a0a1a0b111a0c110a0f0a11180a0b180a091a0c290a0f0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a29230460054f0a260c290a0f0a11180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c26054a0b290b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1c0b0a180a15160c230b150b1b180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c200a20370038000c180a2036000b1338050c1d0b0804ac010b1d06000000000000000038060a1234380c0c210c2a05b40138060a12340b1d060000000000000000380b0c2a0c210b2a0b210c1e0c270b240d1e0d270b12340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c250b1e0c280b250c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404db0105df010b190b1a17270b28380d022c010401002bd20138040c10350b10350c170c160b06040d381a0c0e0c0d0514381b0c250c280b250b280c0e0c0d0b0d0b0e0c1c0c1b0a0432000000000000000000000000000000002104660a170a0c180a0a1a0a1c160c110a160a1c180a111a0c0f0a1b0a17180a0c180a0a1a0b111a0c110a0f0a11180a0b180a091a0c290a0f0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a2923045e054d0a260c290a0f0a11180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c2605480b290b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1c0b0a180a15160c230b150b1b180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c200a20370038000c180a2036000b1338050c1d0b0804aa010b1d06000000000000000038060b1234380c0c210c2a05b20138060b12340b1d060000000000000000380b0c2a0c210b2a0b210c1e0c270b240b1e381c0c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404cb0105cf010b190b1a17270b273811022d010401002cec010b050407380e0c0f0c0e0c0d0511380f0c310c240c2c0b240b2c0b310c0f0c0e0c0d0b0d0b0e0b0f010c11350b11350c170c160b06042138020c2e0c27052838030c2a0c300b2a0c270b300c2e0b270b2e0c1d0c1c0a04320000000000000000000000000000000021047a0a170a0c180a0a1a0a1d160c120a160a1d180a121a0c100a1c0a17180a0c180a0a1a0b121a0c120a100a12180a0b180a091a0c320a100a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c280a280a3223047205610a280c320a100a12180a0b180a091a0a281a0b281632020000000000000000000000000000001a0c28055c0b320b10170a0b180a091a0c040a040b0b180c140b160b09180a14160c210b140b17180b211a0b0c180c150b1d0b0a180a15160c220b150b1c180b221a0c180a180a04170b0317010b04340c1307010c230a233c000c200a20370038000c190a2036000b133805381d0c1e380a0c250b0704be010b1e0b180b25320000000000000000000000000000000038080c290c2f0c2b0c2d05c7010b2532000000000000000000000000000000000b1e0b1838070c2f0c290c2d0c2b0d2b0b2938010d2d0b2f38090b2b0c1f0b2d0c260a2036000b1f38010b190b02160c1a0b20370038000c1b0a1b0a1a2404e20105e6010b1a0b1b17270b233c0136010b263809022e010401002dd5010b050407380e0c0f0c0e0c0d0511380f0c2b0c260c2a0b260b2a0b2b0c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c1a0c1938040c14350b14350c200c1f0a0432000000000000000000000000000000002104700a1a0a0c180a0a1a0a20160c150a190a20180a151a0c120a1f0a1a180a0c180a0a1a0b151a0c150a120a15180a0b180a091a0c2c0a120a15180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2c23046805570a290c2c0a120a15180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c2905520b2c0b12170a0b180a091a0c040a040b0b180c170b190b09180a17160c240b170b1a180b241a0b0c180c180b200b0a180a18160c250b180b1f180b251a0c1b0a1b0a04170b0317010b04340c1607013c000c230a23370038000c1c0a2336000b163805381d0c21380a0c270b0704b1010b210600000000000000000b270b1b34380b0c100c1105b9010b270b1b340b21060000000000000000380c0c110c100b110b100c220c280a2336000b2238010b1c0b02160c1d0b23370038000c1e0a1e0a1d2404ce0105d2010b1d0b1e17270b28380d022f010401002ec6010b050407380e0c0f0c0e0c0d0511380f0c280c230c260b230b260b280c0f0c0e0c0d0b0d0b0e0b0f010c12350b12350c190c180b06042138120c130c11052838130c240c270b240c110b270c130b11350b13350c1e0c1d0a04320000000000000000000000000000000021047c0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c100a1d0a19180a0c180a0a1a0b141a0c140a100a14180a0b180a091a0c290a100a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2923047405630a250c290a100a14180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25055e0b290b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c210b160b19180b211a0b0c180c170b1e0b0a180a17160c220b170b1d180b221a0a04170b0317010b04340c1507013c000c200a20370038000c1a0a2036000b153805381d06000000000000000038140c1f0a2036000b1f38010b1a0b02160c1b0b20370038000c1c0a1c0a1b2404c10105c5010b1b0b1c17270230010401002fde010b050407380e0c0f0c0e0c0d0511380f0c2c0c270c2b0b270b2b0b2c0c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c1a0c190b0604243815353816350c110c10052a3817353818350c110c100b100b110c1f0c1e0a04320000000000000000000000000000000021047c0a1a0a0c180a0a1a0a1f160c140a190a1f180a141a0c120a1e0a1a180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2d0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c2a0a2a0a2d23047405630a2a0c2d0a120a14180a0b180a091a0a2a1a0b2a1632020000000000000000000000000000001a0c2a055e0b2d0b12170a0b180a091a0c040a040b0b180c170b190b09180a17160c230b170b1a180b231a0c150a150b0c180c180b1f0b0a180a18160c240b180b1e180b241a0a04170b0317010b04340c1607010c250a253c000c220a22370038000c1b0a2236000b163805381d0c20380a0c280b250d200d280b15340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b280c260b200c290b260c210a2236000b2138010b1b0b02160c1c0b22370038000c1d0a1d0a1c2404d70105db010b1c0b1d17270b29380d02310104010030c8010b050407380e0c0f0c0e0c0d0511380f0c2a0c250c280b250b280b2a0c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c190c180b060421381a0c110c100528381b0c260c290b260b290c110c100b100b110c1e0c1d0a04320000000000000000000000000000000021047a0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c120a1d0a19180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2b0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b23047205610a270c2b0a120a14180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c27055c0b2b0b12170a0b180a091a0c040a040b0b180c160b180b09180a16160c220b160b19180b221a0b0c180c170b1e0b0a180a17160c230b170b1d180b231a0a04170b0317010b04340c1507010c240a243c000c210a21370038000c1a0a2136000b153805381d0c1f0b240b1f381c0c200a2136000b2038010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404c30105c7010b1b0b1c172702320104010031e5010b05040638120c0f0c0e050d38130c220c2a0b220c0e0b2a0c0f0b0e350b0f350c150c140b06041938020c2c0c23052038030c280c2e0b280c230b2e0c2c0b230b2c0c1b0c1a0a0432000000000000000000000000000000002104720a150a0c180a0a1a0a1b160c100a140a1b180a101a0c0d0a1a0a15180a0c180a0a1a0b101a0c100a0d0a10180a0b180a091a0c2f0a0d0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2f23046a05590a250c2f0a0d0a10180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505540b2f0b0d170a0b180a091a0c040a040b0b180c120b140b09180a12160c1f0b120b15180b1f1a0b0c180c130b1b0b0a180a13160c200b130b1a180b201a0c160a160a04170b0317010b04340c1107010c210a213c000c1e0a1e370038000c170a1e36000b113805060000000000000000381e0c1d380a0c260b0704b7010b1d0b160b26320000000000000000000000000000000038080c270c2d0c290c2b05c0010b2632000000000000000000000000000000000b1d0b1638070c2d0c270c2b0c290d290b2738010d2b0b2d38090b290c1c0b2b0c240a1e36000b1c38010b170b02160c180b1e370038000c190a190a182404db0105df010b180b1917270b213c0136010b24380902330104010032ce010b05040638120c110c10050d38130c240c280b240c100b280c110b10350b11350c180c1738040c12350b12350c1e0c1d0a0432000000000000000000000000000000002104680a180a0c180a0a1a0a1e160c130a170a1e180a131a0c0f0a1d0a18180a0c180a0a1a0b131a0c130a0f0a13180a0b180a091a0c290a0f0a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a29230460054f0a250c290a0f0a13180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25054a0b290b0f170a0b180a091a0c040a040b0b180c150b170b09180a15160c220b150b18180b221a0b0c180c160b1e0b0a180a16160c230b160b1d180b231a0c190a190a04170b0317010b04340c1407013c000c210a21370038000c1a0a2136000b143805060000000000000000381e0c20380a0c260b0704aa010b200600000000000000000b260b1934380b0c0d0c0e05b2010b260b19340b20060000000000000000380c0c0e0c0d0b0e0b0d0c1f0c270a2136000b1f38010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404c70105cb010b1b0b1c17270b27380d0234010401002ec6010b05040638120c120c11050d38130c230c260b230c110b260c120b11350b12350c190c180b06041a380e0c0f0c0e0c0d0524380f0c280c240c270b240b270b280c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c1e0c1d0a04320000000000000000000000000000000021047c0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c100a1d0a19180a0c180a0a1a0b141a0c140a100a14180a0b180a091a0c290a100a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2923047405630a250c290a100a14180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25055e0b290b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c210b160b19180b211a0b0c180c170b1e0b0a180a17160c220b170b1d180b221a0a04170b0317010b04340c1507013c000c200a20370038000c1a0a2036000b153805060000000000000000381e38100c1f0a2036000b1f38010b1a0b02160c1b0b20370038000c1c0a1c0a1b2404c10105c5010b1b0b1c172702350104010033d7010b05040638120c110c10050d38130c250c290b250c100b290c110b10350b11350c180c170b06041c3815353816350c0e0c0d05223817353818350c0e0c0d0b0d0b0e0c1d0c1c0a0432000000000000000000000000000000002104740a180a0c180a0a1a0a1d160c120a170a1d180a121a0c0f0a1c0a18180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c2a0a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a2a23046c055b0a260c2a0a0f0a12180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c2605560b2a0b0f170a0b180a091a0c040a040b0b180c150b170b09180a15160c210b150b18180b211a0c130a130b0c180c160b1d0b0a180a16160c220b160b1c180b221a0a04170b0317010b04340c1407010c230a233c000c200a20370038000c190a2036000b143805060000000000000000381e0c1f380a0c270b230d1f0d270b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c240b1f0c280b240c1e0a2036000b1e38010b190b02160c1a0b20370038000c1b0a1b0a1a2404d00105d4010b1a0b1b17270b28380d02360104010034c1010b05040638120c110c10050d38130c230c260b230c100b260c110b10350b11350c170c160b060419381a0c0e0c0d0520381b0c240c270b240b270c0e0c0d0b0d0b0e0c1c0c1b0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1c160c120a160a1c180a121a0c0f0a1b0a17180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c280a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2823046a05590a250c280a0f0a12180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505540b280b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c200b140b17180b201a0b0c180c150b1c0b0a180a15160c210b150b1b180b211a0a04170b0317010b04340c1307010c220a223c000c1f0a1f370038000c180a1f36000b133805060000000000000000381e0c1e0b220b1e381c0c1d0a1f36000b1d38010b180b02160c190b1f370038000c1a0a1a0a192404bc0105c0010b190b1a172702370104010035f9010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c150c140b06041938020c2c0c24052038030c2a0c2f0b2a0c240b2f0c2c0b240b2c0c1b0c1a0a0432000000000000000000000000000000002104720a150a0c180a0a1a0a1b160c100a140a1b180a101a0c0f0a1a0a15180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c300a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a3023046a05590a260c300a0f0a10180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c2605540b300b0f170a0b180a091a0c040a040b0b180c120b140b09180a12160c200b120b15180b201a320b000000000000000000000000000000170b0c180c130b1b0b0a180a13160c210b130b1a180b211a320b000000000000000000000000000000170c160a160a04170b0317010b04340c1107010c220a223c000c1f0a1f370038000c170a1f36000a1138050c1c38060c270a220d1c0d270b11340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b270c230b1c0c280b230c1e0b0704cb010b1e0b160b28320000000000000000000000000000000038080c290c2e0c2b0c2d05d4010b2832000000000000000000000000000000000b1e0b1638070c2e0c290c2d0c2b0d2b0b2938010d2d0b2e38090b2b0c1d0b2d0c250a1f36000b1d38010b170b02160c180b1f370038000c190a190a182404ef0105f3010b180b1917270b223c0136010b25380902380104010036e4010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c180c1738040c12350b12350c1e0c1d0a0432000000000000000000000000000000002104680a180a0c180a0a1a0a1e160c130a170a1e180a131a0c110a1d0a18180a0c180a0a1a0b131a0c130a110a13180a0b180a091a0c2b0a110a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b230460054f0a270c2b0a110a13180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c27054a0b2b0b11170a0b180a091a0c040a040b0b180c150b170b09180a15160c230b150b18180b231a320b000000000000000000000000000000170b0c180c160b1e0b0a180a16160c240b160b1d180b241a320b000000000000000000000000000000170c190a190a04170b0317010b04340c1407010c250a253c000c220a22370038000c1a0a2236000a1438050c1f38060c280b250d1f0d280b14340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b280c260b1f0c290b260c210b0704c0010b210600000000000000000b290b1934380b0c0f0c1005c8010b290b19340b21060000000000000000380c0c100c0f0b100b0f0c200c2a0a2236000b2038010b1a0b02160c1b0b22370038000c1c0a1c0a1b2404dd0105e1010b1b0b1c17270b2a380d02390104010037e0010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c190c180b06041a380e0c110c100c0f0524380f0c2b0c260c2a0b260b2a0b2b0c110c100c0f0b0f0b100b11010c13350b13350c1e0c1d0a04320000000000000000000000000000000021047c0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c120a1d0a19180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2c0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2c23047405630a290c2c0a120a14180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c29055e0b2c0b12170a0b180a091a0c040a040b0b180c160b180b09180a16160c220b160b19180b221a320b000000000000000000000000000000170b0c180c170b1e0b0a180a17160c230b170b1d180b231a320b000000000000000000000000000000170a04170b0317010b04340c1507010c240a243c000c210a21370038000c1a0a2136000a1538050c1f38060c270b240d1f0d270b15340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b270c250b1f0c280b2538100c200a2136000b2038010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404d90105dd010b1b0b1c17270b283811023a0104010038d9010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c170c160b06041938120c110c10052038130c240c280b240c100b280c110b10350b11350c1c0c1b0a0432000000000000000000000000000000002104740a170a0c180a0a1a0a1c160c120a160a1c180a121a0c0f0a1b0a17180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c290a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2923046c055b0a250c290a0f0a12180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505560b290b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c200b140b17180b201a320b000000000000000000000000000000170b0c180c150b1c0b0a180a15160c210b150b1b180b211a320b000000000000000000000000000000170a04170b0317010b04340c1307010c220a223c000c1f0a1f370038000c180a1f36000a1338050c1d38060c260b220d1d0d260b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b260c230b1d0c270b2306000000000000000038140c1e0a1f36000b1e38010b180b02160c190b1f370038000c1a0a1a0a192404d20105d6010b190b1a17270b273811023b0104010039d9010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c170c160b060419381a0c100c0f0520381b0c250c290b250b290c100c0f0b0f0b100c1c0c1b0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1c160c120a160a1c180a121a0c110a1b0a17180a0c180a0a1a0b121a0c120a110a12180a0b180a091a0c2a0a110a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2a23046a05590a270c2a0a110a12180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705540b2a0b11170a0b180a091a0c040a040b0b180c140b160b09180a14160c210b140b17180b211a320b000000000000000000000000000000170b0c180c150b1c0b0a180a15160c220b150b1b180b221a320b000000000000000000000000000000170a04170b0317010b04340c1307010c230a233c000c200a20370038000c180a2036000a1338050c1d38060c280a230d1d0d280b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b280c240b1d0c260b240c1e0b230b1e381c0c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404d20105d6010b190b1a17270b263811023c010401003ae5010b050406381a0c0e0c0d050d381b0c230c2b0b230b2b0c0e0c0d0b0d0b0e0c150c140b06041738020c2d0c26051e38030c290c2f0b290c260b2f0c2d0b260b2d0c1b0c1a0a0432000000000000000000000000000000002104700a150a0c180a0a1a0a1b160c100a140a1b180a101a0c0f0a1a0a15180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c300a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a3023046805570a270c300a0f0a10180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705520b300b0f170a0b180a091a0c040a040b0b180c120b140b09180a12160c200b120b15180b201a0b0c180c130b1b0b0a180a13160c210b130b1a180b211a0c160a160a04170b0317010b04340c1107010c220a223c000c1f0a1f370038000c170a1f36000b1138050c1c0a220b1c38200c1e380a0c240b0704b7010b1e0b160b24320000000000000000000000000000000038080c280c2e0c2a0c2c05c0010b2432000000000000000000000000000000000b1e0b1638070c2e0c280c2c0c2a0d2a0b2838010d2c0b2e38090b2a0c1d0b2c0c250a1f36000b1d38010b170b02160c180b1f370038000c190a190a182404db0105df010b180b1917270b223c0136010b253809023d010401003bd0010b050406381a0c0e0c0d050d381b0c260c2a0b260b2a0c0e0c0d0b0d0b0e0c180c1738040c12350b12350c1e0c1d0a0432000000000000000000000000000000002104660a180a0c180a0a1a0a1e160c130a170a1e180a131a0c110a1d0a18180a0c180a0a1a0b131a0c130a110a13180a0b180a091a0c2b0a110a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b23045e054d0a270c2b0a110a13180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705480b2b0b11170a0b180a091a0c040a040b0b180c150b170b09180a15160c230b150b18180b231a0b0c180c160b1e0b0a180a16160c240b160b1d180b241a0c190a190a04170b0317010b04340c1407010c250a253c000c220a22370038000c1a0a2236000b1438050c1f0b250b1f38200c21380a0c280b0704ac010b210600000000000000000b280b1934380b0c0f0c1005b4010b280b19340b21060000000000000000380c0c100c0f0b100b0f0c200c290a2236000b2038010b1a0b02160c1b0b22370038000c1c0a1c0a1b2404c90105cd010b1b0b1c17270b29380d023e010401003cc8010b050406381a0c0e0c0d050d381b0c250c280b250b280c0e0c0d0b0d0b0e0c190c180b060418380e0c110c100c0f0522380f0c2a0c260c290b260b290b2a0c110c100c0f0b0f0b100b11010c13350b13350c1e0c1d0a04320000000000000000000000000000000021047a0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c120a1d0a19180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2b0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b23047205610a270c2b0a120a14180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c27055c0b2b0b12170a0b180a091a0c040a040b0b180c160b180b09180a16160c220b160b19180b221a0b0c180c170b1e0b0a180a17160c230b170b1d180b231a0a04170b0317010b04340c1507010c240a243c000c210a21370038000c1a0a2136000b1538050c1f0b240b1f382038100c200a2136000b2038010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404c30105c7010b1b0b1c1727023f010401003dc1010b050406381a0c0e0c0d050d381b0c230c260b230b260c0e0c0d0b0d0b0e0c170c160b06041738120c110c10051e38130c240c270b240c100b270c110b10350b11350c1c0c1b0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1c160c120a160a1c180a121a0c0f0a1b0a17180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c280a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2823046a05590a250c280a0f0a12180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505540b280b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c200b140b17180b201a0b0c180c150b1c0b0a180a15160c210b150b1b180b211a0a04170b0317010b04340c1307010c220a223c000c1f0a1f370038000c180a1f36000b1338050c1d0b220b1d382006000000000000000038140c1e0a1f36000b1e38010b180b02160c190b1f370038000c1a0a1a0a192404bc0105c0010b190b1a17270240010401003ed7010b050406381a0c0e0c0d050d381b0c260c2a0b260b2a0c0e0c0d0b0d0b0e0c180c170b06041a3815353816350c100c0f05203817353818350c100c0f0b0f0b100c1d0c1c0a0432000000000000000000000000000000002104720a180a0c180a0a1a0a1d160c120a170a1d180a121a0c110a1c0a18180a0c180a0a1a0b121a0c120a110a12180a0b180a091a0c2b0a110a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2b23046a05590a290c2b0a110a12180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c2905540b2b0b11170a0b180a091a0c040a040b0b180c150b170b09180a15160c220b150b18180b221a0c130a130b0c180c160b1d0b0a180a16160c230b160b1c180b231a0a04170b0317010b04340c1407010c240a243c000c210a21370038000c190a2136000b1438050c1e0a240b1e38200c20380a0c270b240d200d270b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c250b200c280b250c1f0a2136000b1f38010b190b02160c1a0b21370038000c1b0a1b0a1a2404d00105d4010b1a0b1b17270b28380d02410300003f070b0139000c020b000b023f0002420104003f140a00116a0701210406050b0b0001060000000000000000116b270a000b01382139000c020b000b023f0002430104003f120a00116a0701210406050b0b0001060000000000000000116b27380a39000c010b000b013f000244010400010206ffffffffffffffff2745010400010206ffffffffffffffff27460104000102060000000000000000274701040100415b0b00116a0c030a030701210408050b060000000000000000116b270a033c000c070a0736000b0138050c0a0e0a38000c04116d0101010c0e38040c0d0c0c0b04350610270000000000000b0e1735180c050a050b0d35180c0b0b0c353210270000000000000000000000000000180b05160c090b0b0b091a340c060a060b0226043c05400b07010700273822044a0b0a06000000000000000038060b06380c0c080c0f055138060b060b0a060000000000000000380b0c0f0c080b0736000b0f38010b033c0136010b0838090248010400010206000000000000000027490104000102060000000000000000274a010401004493010b00116a0c040a040701210408050b060000000000000000116b270b03044f38020c140c1238230c0d0c0f0a01350a0d0b0f1735180c050b120b0d35180a05160c0b0b050b14180b0b1a0c070a070b023524042e05300700270a043c000c090a0936000b0138050b073806320000000000000000000000000000000038070c1c0c180c1a0c160d160b1838010d1a0b1c38090b0936000b1638010b043c0136010b1a380905920138020c130c1538230c0e0c100a01350a0e0b101735180c060b130b0e35180a06160c0c0b060b15180b0c1a0c080a080b023524047005720700270a043c010c0a0a0a36010b0138240c11380a32000000000000000000000000000000000b110b0838070c1d0c190c1b0c170d170b1938010d1b0b1d38090b0a36010b1b38090b043c0036000b173801024b010400010206ffffffffffffffff274c0104010045650b00116a0c0d0a0d0701210408050b060000000000000000116b270b08041138120c0b0c0a051838130c160c170b160c0a0b170c0b0b0a350b0b350c100c0f0b030b07180c0e0b0f0b06180a0e160c140b0e0b10180b141a340c0c0a0c0a0526043405380b050b0c17270a0d3c0036000b0438050c150b0904480b1506000000000000000038060b0c38250c130c18054f38060b0c0b1506000000000000000038260c180c130b180b130c1238110e1238270c110a110a0524045b055f0b050b1117270b0d3c0136010b123809024d0104010046650b00116a0c0d0a0d0701210408050b060000000000000000116b270b0804143815353816350c0b0c0a051a3817353818350c0b0c0a0b0a0b0b0c100c0f0b030b07180c0e0b0f0b06180a0e160c140b0e0b10180b141a340c0c0a0c0a0526043405380b050b0c17270a0d3c0036000a0438050c1238060c160a0d0d120d160b040600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b160c150b120c170b150c130e1338270c110a110a05240459055d0b050b1117270b0d3c0136010b1338090b173811024e0104010047590b00116a0c0f0a0f0701210408050b060000000000000000116b270b080412380e0c0c0c0b0c0a051c380f0c180c160c170b160b170b180c0c0c0b0c0a0b0a0b0b0b0c010c0d350b0d350c120c110b030b07180c100b110b06180a10160c150b100b12180b151a340c0e0a0e0a0526043c05400b050b0e17270a0f3c0036000b043805381d0c140e1438270c130a130a0524044f05530b050b1317270b0f3c0136010b143809024f03000100030a0b000b0138210c0207013c0036000b02380102500004010026170a00116a0c020a020701210408050d0b0001060000000000000000116b270b000b0138210c030b023c0036000b033801025103000100260c07010c010a013c0036000b0038050c020b010b02382802520004010026150b00116a0c020a020701210408050b060000000000000000116b270a023c0036000b0138050c030b020b033828025303000100030a07013c0036000b0138050c020b000b02382802540004010026150b00116a0c030a030701210408050b060000000000000000116b270b033c0036000b0238050c040b010b043828025503000100010607013c0036000b003805025603000100010507013c0036003829025703000100491707013c000c030a03370038000c020a000b022404110b0336000b0038050c0105150b03360038290c010b01020000000f001700"; + let res = run_binary_test("sample_coin_store", code); + assert!(res.is_ok(), "{:?}", res) +} + +#[test] +fn sample_liquidity_pool() { + let code = "a11ceb0b050000000e0100240224ab0103cf01b6030485056405e905eb0507d40bde0d08b2196006921ab80110ca1bd8070aa223ef010b9125160ca725c9120df0372a0e9a38280000010101020103010401050106000700080009000a000b000c000d000e000f021002110012080300010001000100130003000100010001001406030001000100010015060300010001000100160803000100010001001706030001000100010018060300010001000100190800001a0603000100010001001b0603000100010001001c0603000100010001001d06030001000100010220040100010d210003000100010001033804010601024f05010001025105010001015b0600105e0700027305010001057407001185010700001e00010100001f01010300000000220203030000000023040503000000002401060300000000250107030000000026010403000000002701040300000000280107030000000029010403000000002a010403000000002b080100002c010903000000002d010903000000002e030203000000002f0a0b01000030050103000000003108010300000000320c010300000000330c010300000000340d010300000000350e030300000000360d0103000000085f010901000f6011120010611314000862010901001063151200106407120010651612000766010902000002671c0701000768011501000e691e0700026a1f200100022221010100036b230101060a6c010100046d0828000c6e0827000b2b0801000a2b0801000e6f0415000e7015070002712a010100022e2b2001000e722e070007750101010008760101010001773334000778013503000000022b36370100027938010100027a011401000e7b140700027c012001000b7d010701000b7e0107000931080103000000017f083a01060b80010128000b81010701000b82010701000983014101030000000684010107001186010444001187014415000e88010b150017101a101e1a01181f1b201b1f101f1d2210221d1618231b2422051808182c102c1d2d1b242c0f300030141824312f102f1d30303218331b341b17303510351d3710371d38303a183b393b2c3b223b3b3b313b3c3b3d3b3e2439243e243d3f18243b243c0603030404040400010b0c010b0d03090009010902020b0c0109000b0c010901020303030b0c0109000b0c0109010b010309000901090203040403010301060c010105030303030302040402060c0303070b04030900090109020303040b0c010900030b0c0109010307020208120812081204081201090004040304030108120206081206081201020104020812081201060b0403090009010902030900090109020b0103070b000309000901090204070b04030900090109020b0c01090003030b0c01090103030209000901010b0d0309000901090201060b0c0109000109010304040402070b0c01090003010b0c010900020b0c010900060b10010900010b050309000901090202070b0e01090009000601070b040309000901090203030b0c0109000b0c01090104030404060b040309000901090203060b0403090009010902030301081101050e0303070b0003090009010902030b0c010b0d0309000901090204070b04030900090109020303030303030302070b0c0109000b0c0109000203060b0f010900010b030309000901090206040404040404030303030b01070b0003090009010902070b04030900090109020303040303030403010902010b02030900090109020b0b00030900090109020b10010b0d030900090109020b13010b0d030900090109020b0f010b0d03090009010902081408140b04030900090109020c060807030301060811010c020814081405060c081408140201030b100109000b130109000b0f010900010b13010900010b0803090009010902010b0e010900010b0903090009010902010b0603090009010902010b0b03090009010902010b0a0309000901090202070b0003090009010902070b040309000901090208030303030b0c010900030b0c0109010303050b0c0109000b0c010901100103030303070b0e010b0903090009010902070b0003090009010902070b04030900090109020304030b0c0109000304030b0c01090108010103070b0003090009010902030404040108150e6c69717569646974795f706f6f6c076163636f756e7404636f696e056576656e74067369676e657206737472696e670974696d657374616d700b636f696e5f68656c706572066375727665730b64616f5f73746f7261676509656d657267656e63790d676c6f62616c5f636f6e6669670a6c705f6163636f756e74076c705f636f696e046d6174680c737461626c655f6375727665047532353607757136347836340b4576656e747353746f726509466c6173686c6f616e0e466c6173686c6f616e4576656e74134c697175696469747941646465644576656e740d4c6971756964697479506f6f6c154c697175696469747952656d6f7665644576656e74124f7261636c65557064617465644576656e7415506f6f6c4163636f756e744361706162696c69747910506f6f6c437265617465644576656e7409537761704576656e741155706461746544414f4665654576656e740e5570646174654665654576656e741c6173736572745f6c705f76616c75655f69735f696e63726561736564146173736572745f706f6f6c5f756e6c6f636b656404436f696e024c50046275726e09666c6173686c6f616e156765745f63756d756c61746976655f7072696365730b6765745f64616f5f666565136765745f64616f5f666565735f636f6e666967136765745f646563696d616c735f7363616c6573076765745f6665650f6765745f666565735f636f6e666967116765745f72657365727665735f73697a650a696e697469616c697a650e69735f706f6f6c5f6578697374730e69735f706f6f6c5f6c6f636b6564046d696e741e6e65775f72657365727665735f61667465725f666565735f7363616c65640d7061795f666c6173686c6f616e0872656769737465720b7365745f64616f5f666565077365745f6665651073706c69745f6665655f746f5f64616f04737761700d7570646174655f6f7261636c6513706f6f6c5f637265617465645f68616e646c650b4576656e7448616e646c65166c69717569646974795f61646465645f68616e646c65186c69717569646974795f72656d6f7665645f68616e646c650b737761705f68616e646c6510666c6173686c6f616e5f68616e646c65156f7261636c655f757064617465645f68616e646c65117570646174655f6665655f68616e646c65157570646174655f64616f5f6665655f68616e646c6506785f6c6f616e06795f6c6f616e04785f696e05785f6f757404795f696e05795f6f75740b61646465645f785f76616c0b61646465645f795f76616c126c705f746f6b656e735f72656365697665640e636f696e5f785f726573657276650e636f696e5f795f72657365727665146c6173745f626c6f636b5f74696d657374616d70176c6173745f70726963655f785f63756d756c6174697665176c6173745f70726963655f795f63756d756c61746976650b6c705f6d696e745f6361700e4d696e744361706162696c6974790b6c705f6275726e5f6361700e4275726e4361706162696c69747907785f7363616c6507795f7363616c65066c6f636b6564036665650764616f5f6665650e72657475726e65645f785f76616c0e72657475726e65645f795f76616c106c705f746f6b656e735f6275726e65640a7369676e65725f636170105369676e65724361706162696c6974790763726561746f72076e65775f66656504553235360969735f737461626c65086c705f76616c756507636f6d706172650f69735f756e636f7272656c617465640966726f6d5f753132380866726f6d5f753634036d756c0969735f736f727465640576616c756506737570706c790c6d756c5f6469765f7531323807657874726163740a656d69745f6576656e74136173736572745f6e6f5f656d657267656e63790a616464726573735f6f661372657472696576655f7369676e65725f6361700b6d756c5f746f5f753132380473717274056d65726765076d756c5f64697610467265657a654361706162696c69747906537472696e670e6173736572745f69735f636f696e126173736572745f76616c69645f63757276651d6372656174655f7369676e65725f776974685f6361706162696c6974791b67656e65726174655f6c705f6e616d655f616e645f73796d626f6c1264657374726f795f667265657a655f63617008646563696d616c7306706f775f3130047a65726f0f6765745f64656661756c745f666565136765745f64656661756c745f64616f5f666565106e65775f6576656e745f68616e646c650d6765745f6665655f61646d696e146173736572745f76616c69645f64616f5f666565106173736572745f76616c69645f666565076465706f7369740b6e6f775f7365636f6e64730755513634783634086672616374696f6e07746f5f753132380c6f766572666c6f775f61646449bcc662ad23bb4f134aad8c8117c03f238bf3f03f324afe91ce231a559e8a6b00000000000000000000000000000000000000000000000000000000000000014e9fce03284c0ce0b86c88dd5a46f050cad2f4f33c4cdd29d98f501868558c81030864000000000000000308680000000000000003086e0000000000000003086a000000000000000308690000000000000003087000000000000000030866000000000000000308670000000000000003086d0000000000000003086b000000000000000308650000000000000003086f0000000000000003086c00000000000000030810270000000000000308e803000000000000052049bcc662ad23bb4f134aad8c8117c03f238bf3f03f324afe91ce231a559e8a6b126170746f733a3a6d657461646174615f7630c3070d6400000000000000174552525f57524f4e475f504149525f4f52444552494e47335768656e20636f696e73207573656420746f20637265617465207061697220686176652077726f6e67206f72646572696e672e6500000000000000184552525f504f4f4c5f4558495354535f464f525f50414952245768656e207061697220616c726561647920657869737473206f6e206163636f756e742e6600000000000000204552525f4e4f545f454e4f5547485f494e495449414c5f4c4951554944495459215768656e206e6f7420656e6f756768206c6971756964697479206d696e7465642e6700000000000000184552525f4e4f545f454e4f5547485f4c4951554944495459215768656e206e6f7420656e6f756768206c6971756964697479206d696e7465642e6800000000000000114552525f454d5054595f434f494e5f494e335768656e20626f7468205820616e6420592070726f766964656420666f7220737761702061726520657175616c207a65726f2e6900000000000000124552525f494e434f52524543545f535741504b5768656e20696e636f727265637420494e732f4f55547320617267756d656e74732070617373656420647572696e67207377617020616e64206d61746820646f65736e277420776f726b2e6a00000000000000194552525f494e434f52524543545f4255524e5f56414c5545531d496e636f7272656374206c7020636f696e206275726e2076616c7565736b00000000000000174552525f504f4f4c5f444f45535f4e4f545f4558495354225768656e20706f6f6c20646f65736e27742065786973747320666f7220706169722e6c000000000000000f4552525f554e524541434841424c451353686f756c64206e65766572206f636375722e6d00000000000000284552525f4e4f545f454e4f5547485f5045524d495353494f4e535f544f5f494e495449414c495a45525768656e2060696e697469616c697a65282960207472616e73616374696f6e206973207369676e6564207769746820616e79206163636f756e74206f74686572207468616e20406c6971756964737761702e6e00000000000000134552525f454d5054595f434f494e5f4c4f414e385768656e20626f7468205820616e6420592070726f766964656420666f7220666c6173686c6f616e2061726520657175616c207a65726f2e6f00000000000000124552525f504f4f4c5f49535f4c4f434b4544145768656e20706f6f6c206973206c6f636b65642e70000000000000000d4552525f4e4f545f41444d494e165768656e2075736572206973206e6f742061646d696e000208370b0e010b0803090009010902390b0e010b03030900090109023a0b0e010b05030900090109023b0b0e010b09030900090109023c0b0e010b02030900090109023d0b0e010b06030900090109023e0b0e010b0b030900090109023f0b0e010b0a0309000901090201020240034103020204420343034403450303020346034703480304020c490b0c0109004a0b0c0109014b034c044d044e0b0f010b0d03090009010902500b10010b0d03090009010902520353035401550356030502035703580359030602024c044d040702015a08110802015c0509020442034303440345030a02015d030b02015d0304180018051801180318021808180a180b1809180618000000000f3c38000303051a0b020a000b030a0111180c0a0b040b000b050b0111180c080e080e0a11190c060b063102210319070427053b3801031d05390b020b03180c0b0b0b111b070d070d18111c111d0c0c0b04111b0b05111b111d0c090e090e0c11190c070b07310221033b070427070c27020100000104170c070f3d000c000b003700140921030b070b2702020100020004195938020304070027070f3b00030907092738030e0038040c02070f3c000c0538050c040a05370138060c070a05370238070c0a0a02350a07350a0411210c080a02350a0a350b0411210c0b0a0806000000000000000024032d05320a0b060000000000000000240c010534090c010b01033a0b05010703270a0536010a0838080c060a0536020a0b38090c090a050b070b0a380a0b000b053703380b070f3c010c030b0336040b080b0b0b023902380c0b060b0902030100020004243e112538020305070027070f3b00030a07092738030a000600000000000000002403100513080c0205170a01060000000000000000240c020b02031b070227070f3c000c030a03370138060c040a03370238070c050a0336010a0038080c060a0336020a0138090c07080a033600150b030b040b05380a0b060b070b000b013903020401000104251e112538020305070027070f3b00030a0709273803070f3d000c030a033705140c010a033706140c020b033707140c000b010b020b00020501000104171038020304070027070f3b000309070927070f3d000c000b003708140206010001040103380d0700020701000104171338020304070027070f3b000309070927070f3d000c000a003709140b00370a14020801000104171038020304070027070f3b000309070927070f3d000c000b00370b140209010001040103380e070d020a010001042619112538020305070027070f3b00030a0709273803070f3d000c000a00370138060c010b00370238070c020b010b02020b01040027150a001126070f2103090b00010708270a0011270c010a000b0112072d070a0011280b001129020c010000010738020304070027070f3b00020d01000104171038020304070027070f3b000309070927070f3d000c000b00370014020e01000200042976112538020305070027070f3b00030a070927380338050c07070f3c000c080a08370138060c0c0a08370238070c0f0e0038060c0b0e0138070c0e0a07320000000000000000000000000000000021032305350a0b0a0e112a112b0c050a05070e2403300b08010706270b05070e170c03054f0a0b350a070a0c3511210c0a0a0e350b070a0f3511210c0d0a0a0a0d230348054b0b0a0c02054d0b0d0c020b020c030b030c090a090600000000000000002403590b08010707270a0836010b00380f0a0836020b0138100a090a08370c38110c060b080b0c0b0f380a070f3c010c040b04360d0b0b0b0e0b09390438120b06020f0000002d3b38010303050c0b00070d112a0b020a04112a170c06051a38000310070c270b000b020a04070d112e17350c050b050c060b060c093801031f05280b01070d112a0b030b04112a170c0805363800032c070c270b010b030b04070d112e17350c070b070c080b080c0a0b090b0a021001000200042f6e112538020305070027070f3b00030a0709270b023a030c0b0c070e0038060c060e0138070c0a0a06060000000000000000240319051c080c0305200a0a060000000000000000240c030b030324070127070f3c000c050a05370138060c090a05370238070c0d0b090a07160c090b0d0a0b160c0d0a0536010b00380f0a0536020b0138100a05370138060a05370238070a060a0a0a05370b1438130c0c0c080a053709140a05370a140b09350b0d350b080b0c38140a050a060a0a3815090b05360015070f3c010c040b04360e0b060b070b0a0b0b390538160211010001073263112538173818380203090b00010700273819070f3b002003120b0001070a27070f2b070c090b09100f11310c08381a0c060c050e080b050b06310608381b0c040c030c020b03381c0600000000000000000c0a0600000000000000000c0b381d032e0534381e11360c0a381f11360c0b38203821060000000000000000320000000000000000000000000000000032000000000000000000000000000000000b040b020b0a0b0b093822113939000c070e080b073f000e0838230e0838240e0838250e0838260e0838270e0838280e0838290e08382a0e08382b39010c010d01360f0b0011263906382c0e080b013f01021201040200043f27380203060b0001070027070f3b00030d0b000107092738030b001126113c2103150705270a01113d070f3c000c030a010b03360815070f3c010c020b0236100b013907382d021301040200043f27380203060b0001070027070f3b00030d0b000107092738030b001126113c2103150705270a01113e070f3c000c030a010b03360b15070f3c010c020b0236110b013908382e0214000000403b0a00370b140c0a0a003708140c040a0a0a0418070019060000000000000000220311051a0b0a0b041807001a060100000000000000160c0305200b0a0b041807001a0c030b030c050b010a05070d112e0c060b020b05070d112e0c080a0036010b0638080c070b0036020b0838090c09070f0b070b09382f02150100020004427b112538020305070027070f3b00030a07092738030e0038060c0c0e0238070c100a0c0600000000000000002403160519080c04051d0a10060000000000000000240c040b040321070127070f3c000c0b0a0b370138060c0e0a0b370238070c120a0b36010b00380f0a0b36020b0238100a0b36010a0138080c0f0a0b36020a0338090c130a0b370138060a0b370238070a0c0a100a0b370b1438130c110c0d0a0b3709140a0b370a140a0e350a12350b0d350b113538140a0b0a0c0a1038150b0b0b0e0b12380a070f3c010c0a0b0a36120c090b0c0c050b100c060b010c070b030c080b090b050b070b060b08390938300b0f0b1302160000010043540a003707140c0711400c050a050b0717350c0a0a0a320000000000000000000000000000000024031005150a01060000000000000000220c030517090c030b03031a051f0a02060000000000000000220c040521090c040b040324054f0a020a01114111420a0a180c080b010b02114111420b0a180c090a003705140b0811430a003605150a003706140b0911430a00360615070f3c010c060b0636130a003705140a00370614390a38310b050b003607150204090400040104060002040304040402040b04070408040a04050001000407000000000700060003000500180118021803180418051806180718081809180a180b180c180d180e181018111812181318141800"; + let res = run_binary_test("sample_liquidity_pool", code); + assert!(res.is_ok(), "{:?}", res) +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions new file mode 100644 index 000000000..6baf2ee61 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions @@ -0,0 +1,10 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 2beb0a0e65962432af560e626fa109d269b07db8807968413425f0bb14bb3667 # shrinks to module = CompiledModule: { struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } +cc c14ae393a6eefae82c0f4ede2acaa0aa0e993c1bba3fe3e5958e6e31cb5d2957 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [] +cc 88615e15ef42d29405cd91d6d0a573ccbeb833d0c7471f718ee794bc5ba399ca # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x4, field_count: 0, fields: 0 }, StructDefinition { struct_handle: 2, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [OutOfBoundsMutation { src_kind: StructDefinition, src_idx: Index(0), dst_kind: FieldDefinition, offset: 0 }] +cc a34039f5d57751762a6eacf3ca3a2857781fb0bd0af0b7a06a9427f896f29aa9 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] struct_handles: [ StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, StructHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false },] function_handles: [ FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(0) }, FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), signature: FunctionSignatureIndex(1) },] struct_defs: [ StructDefinition { struct_handle: 1, access: 0x2, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x0, code: CodeUnit { max_stack_size: 0, locals: 0 code: [ BrTrue(1),] } },] type_signatures: [ TypeSignature(Unit), TypeSignature(Unit),] function_signatures: [ FunctionSignature { return_type: Unit, arg_types: [] }, FunctionSignature { return_type: Unit, arg_types: [] },] locals_signatures: [ LocalsSignature([]),] string_pool: [ "",] address_pool: [ Address([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),] } , oob_mutations = [] diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs new file mode 100644 index 000000000..69df69c40 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs @@ -0,0 +1,464 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use invalid_mutations::bounds::{ + ApplyCodeUnitBoundsContext, ApplyOutOfBoundsContext, CodeUnitBoundsMutation, + OutOfBoundsMutation, +}; +use move_binary_format::{ + check_bounds::BoundsChecker, file_format::*, file_format_common, + proptest_types::CompiledModuleStrategyGen, +}; +use move_core_types::{ + account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, +}; +use proptest::{collection::vec, prelude::*}; + +#[test] +fn empty_module_no_errors() { + BoundsChecker::verify_module(&basic_test_module()).unwrap(); +} + +#[test] +fn empty_script_no_errors() { + BoundsChecker::verify_script(&basic_test_script()).unwrap(); +} + +#[test] +fn invalid_default_module() { + BoundsChecker::verify_module(&CompiledModule { + version: file_format_common::VERSION_MAX, + ..Default::default() + }) + .unwrap_err(); +} + +#[test] +fn invalid_self_module_handle_index() { + let mut m = basic_test_module(); + m.self_module_handle_idx = ModuleHandleIndex(12); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_type_param_in_fn_return_() { + use SignatureToken::*; + + let mut m = basic_test_module(); + m.function_handles[0].return_ = SignatureIndex(1); + m.signatures.push(Signature(vec![TypeParameter(0)])); + assert_eq!(m.signatures.len(), 2); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_type_param_in_fn_parameters() { + use SignatureToken::*; + + let mut m = basic_test_module(); + m.function_handles[0].parameters = SignatureIndex(1); + m.signatures.push(Signature(vec![TypeParameter(0)])); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_type_param_in_script_parameters() { + use SignatureToken::*; + + let mut s = basic_test_script(); + s.parameters = SignatureIndex(1); + s.signatures.push(Signature(vec![TypeParameter(0)])); + assert_eq!( + BoundsChecker::verify_script(&s).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_struct_in_fn_return_() { + use SignatureToken::*; + + let mut m = basic_test_module(); + m.function_handles[0].return_ = SignatureIndex(1); + m.signatures + .push(Signature(vec![Struct(StructHandleIndex::new(1))])); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_type_param_in_field() { + use SignatureToken::*; + + let mut m = basic_test_module(); + match &mut m.struct_defs[0].field_information { + StructFieldInformation::Declared(ref mut fields) => { + fields[0].signature.0 = TypeParameter(0); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); + } + _ => panic!("attempt to change a field that does not exist"), + } +} + +#[test] +fn invalid_struct_in_field() { + use SignatureToken::*; + + let mut m = basic_test_module(); + match &mut m.struct_defs[0].field_information { + StructFieldInformation::Declared(ref mut fields) => { + fields[0].signature.0 = Struct(StructHandleIndex::new(3)); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); + } + _ => panic!("attempt to change a field that does not exist"), + } +} + +#[test] +fn invalid_struct_with_actuals_in_field() { + use SignatureToken::*; + + let mut m = basic_test_module(); + match &mut m.struct_defs[0].field_information { + StructFieldInformation::Declared(ref mut fields) => { + fields[0].signature.0 = + StructInstantiation(StructHandleIndex::new(0), vec![TypeParameter(0)]); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH + ); + } + _ => panic!("attempt to change a field that does not exist"), + } +} + +#[test] +fn invalid_locals_id_in_call() { + use Bytecode::*; + + let mut m = basic_test_module(); + m.function_instantiations.push(FunctionInstantiation { + handle: FunctionHandleIndex::new(0), + type_parameters: SignatureIndex::new(1), + }); + let func_inst_idx = FunctionInstantiationIndex(m.function_instantiations.len() as u16 - 1); + m.function_defs[0].code.as_mut().unwrap().code = vec![CallGeneric(func_inst_idx)]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn script_invalid_locals_id_in_call() { + use Bytecode::*; + + let mut s = basic_test_script(); + s.function_instantiations.push(FunctionInstantiation { + handle: FunctionHandleIndex::new(0), + type_parameters: SignatureIndex::new(1), + }); + let func_inst_idx = FunctionInstantiationIndex(s.function_instantiations.len() as u16 - 1); + s.code.code = vec![CallGeneric(func_inst_idx)]; + assert_eq!( + BoundsChecker::verify_script(&s).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_type_param_in_call() { + use Bytecode::*; + use SignatureToken::*; + + let mut m = basic_test_module(); + m.signatures.push(Signature(vec![TypeParameter(0)])); + m.function_instantiations.push(FunctionInstantiation { + handle: FunctionHandleIndex::new(0), + type_parameters: SignatureIndex::new(1), + }); + let func_inst_idx = FunctionInstantiationIndex(m.function_instantiations.len() as u16 - 1); + m.function_defs[0].code.as_mut().unwrap().code = vec![CallGeneric(func_inst_idx)]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn script_invalid_type_param_in_call() { + use Bytecode::*; + use SignatureToken::*; + + let mut s = basic_test_script(); + s.signatures.push(Signature(vec![TypeParameter(0)])); + s.function_instantiations.push(FunctionInstantiation { + handle: FunctionHandleIndex::new(0), + type_parameters: SignatureIndex::new(1), + }); + let func_inst_idx = FunctionInstantiationIndex(s.function_instantiations.len() as u16 - 1); + s.code.code = vec![CallGeneric(func_inst_idx)]; + assert_eq!( + BoundsChecker::verify_script(&s).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_struct_as_type_actual_in_exists() { + use Bytecode::*; + use SignatureToken::*; + + let mut m = basic_test_module(); + m.signatures + .push(Signature(vec![Struct(StructHandleIndex::new(3))])); + m.function_instantiations.push(FunctionInstantiation { + handle: FunctionHandleIndex::new(0), + type_parameters: SignatureIndex::new(1), + }); + let func_inst_idx = FunctionInstantiationIndex(m.function_instantiations.len() as u16 - 1); + m.function_defs[0].code.as_mut().unwrap().code = vec![CallGeneric(func_inst_idx)]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn script_invalid_struct_as_type_argument_in_exists() { + use Bytecode::*; + use SignatureToken::*; + + let mut s = basic_test_script(); + s.signatures + .push(Signature(vec![Struct(StructHandleIndex::new(3))])); + s.function_instantiations.push(FunctionInstantiation { + handle: FunctionHandleIndex::new(0), + type_parameters: SignatureIndex::new(1), + }); + let func_inst_idx = FunctionInstantiationIndex(s.function_instantiations.len() as u16 - 1); + s.code.code = vec![CallGeneric(func_inst_idx)]; + assert_eq!( + BoundsChecker::verify_script(&s).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_friend_module_address() { + let mut m = basic_test_module(); + m.friend_decls.push(ModuleHandle { + address: AddressIdentifierIndex::new(m.address_identifiers.len() as TableIndex), + name: IdentifierIndex::new(0), + }); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_friend_module_name() { + let mut m = basic_test_module(); + m.friend_decls.push(ModuleHandle { + address: AddressIdentifierIndex::new(0), + name: IdentifierIndex::new(m.identifiers.len() as TableIndex), + }); + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn script_missing_signature() { + // The basic test script includes parameters pointing to an empty signature. + let mut s = basic_test_script(); + // Remove the empty signature from the script. + s.signatures.clear(); + // Bounds-checking the script should now result in an out-of-bounds error. + assert_eq!( + BoundsChecker::verify_script(&s).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); +} + +#[test] +fn invalid_signature_for_vector_operation() { + use Bytecode::*; + + let skeleton = basic_test_module(); + let sig_index = SignatureIndex(skeleton.signatures.len() as u16); + for bytecode in vec![ + VecPack(sig_index, 0), + VecLen(sig_index), + VecImmBorrow(sig_index), + VecMutBorrow(sig_index), + VecPushBack(sig_index), + VecPopBack(sig_index), + VecUnpack(sig_index, 0), + VecSwap(sig_index), + ] { + let mut m = skeleton.clone(); + m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); + } +} + +#[test] +fn invalid_struct_for_vector_operation() { + use Bytecode::*; + use SignatureToken::*; + + let mut skeleton = basic_test_module(); + skeleton + .signatures + .push(Signature(vec![Struct(StructHandleIndex::new(3))])); + let sig_index = SignatureIndex((skeleton.signatures.len() - 1) as u16); + for bytecode in vec![ + VecPack(sig_index, 0), + VecLen(sig_index), + VecImmBorrow(sig_index), + VecMutBorrow(sig_index), + VecPushBack(sig_index), + VecPopBack(sig_index), + VecUnpack(sig_index, 0), + VecSwap(sig_index), + ] { + let mut m = skeleton.clone(); + m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); + } +} + +#[test] +fn invalid_type_param_for_vector_operation() { + use Bytecode::*; + use SignatureToken::*; + + let mut skeleton = basic_test_module(); + skeleton.signatures.push(Signature(vec![TypeParameter(0)])); + let sig_index = SignatureIndex((skeleton.signatures.len() - 1) as u16); + for bytecode in vec![ + VecPack(sig_index, 0), + VecLen(sig_index), + VecImmBorrow(sig_index), + VecMutBorrow(sig_index), + VecPushBack(sig_index), + VecPopBack(sig_index), + VecUnpack(sig_index, 0), + VecSwap(sig_index), + ] { + let mut m = skeleton.clone(); + m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; + assert_eq!( + BoundsChecker::verify_module(&m).unwrap_err().major_status(), + StatusCode::INDEX_OUT_OF_BOUNDS + ); + } +} + +proptest! { + #[test] + fn valid_bounds(_module in CompiledModule::valid_strategy(20)) { + // valid_strategy will panic if there are any bounds check issues. + } +} + +/// Ensure that valid modules that don't have any members (e.g. function args, struct fields) pass +/// bounds checks. +/// +/// There are some potentially tricky edge cases around ranges that are captured here. +#[test] +fn valid_bounds_no_members() { + let mut gen = CompiledModuleStrategyGen::new(20); + gen.zeros_all(); + proptest!(|(_module in gen.generate())| { + // gen.generate() will panic if there are any bounds check issues. + }); +} + +proptest! { + #[test] + fn invalid_out_of_bounds( + module in CompiledModule::valid_strategy(20), + oob_mutations in vec(OutOfBoundsMutation::strategy(), 0..40), + ) { + let (module, expected_violations) = { + let oob_context = ApplyOutOfBoundsContext::new(module, oob_mutations); + oob_context.apply() + }; + + let actual_violations = BoundsChecker::verify_module(&module); + prop_assert_eq!(expected_violations.is_empty(), actual_violations.is_ok()); + } + + #[test] + fn code_unit_out_of_bounds( + mut module in CompiledModule::valid_strategy(20), + mutations in vec(CodeUnitBoundsMutation::strategy(), 0..40), + ) { + let expected_violations = { + let context = ApplyCodeUnitBoundsContext::new(&mut module, mutations); + context.apply() + }; + + let actual_violations = BoundsChecker::verify_module(&module); + prop_assert_eq!(expected_violations.is_empty(), actual_violations.is_ok()); + } + + #[test] + fn no_module_handles( + identifiers in vec(any::(), 0..20), + address_identifiers in vec(any::(), 0..20), + ) { + // If there are no module handles, the only other things that can be stored are intrinsic + // data. + let module = CompiledModule { + identifiers, + address_identifiers, + ..Default::default() + }; + + prop_assert_eq!( + BoundsChecker::verify_module(&module).map_err(|e| e.major_status()), + Err(StatusCode::NO_MODULE_HANDLES) + ); + } +} + +proptest! { + // Generating arbitrary compiled modules is really slow, possibly because of + // https://github.com/AltSysrq/proptest/issues/143. + #![proptest_config(ProptestConfig::with_cases(16))] + + /// Make sure that garbage inputs don't crash the bounds checker. + #[test] + fn garbage_inputs(module in any_with::(16)) { + let _ = BoundsChecker::verify_module(&module); + } +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/catch_unwind.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/catch_unwind.rs new file mode 100644 index 000000000..c43d62580 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/catch_unwind.rs @@ -0,0 +1,27 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 +use fail::FailScenario; +use move_binary_format::file_format::empty_module; +use move_core_types::{ + state::{self, VMState}, + vm_status::StatusCode, +}; +use move_vm_config::verifier::VerifierConfig; +use std::panic::{self, PanicInfo}; + +#[ignore] +#[test] +fn test_unwind() { + let scenario = FailScenario::setup(); + fail::cfg("verifier-failpoint-panic", "panic").unwrap(); + + panic::set_hook(Box::new(move |_: &PanicInfo<'_>| { + assert_eq!(state::get_state(), VMState::VERIFIER); + })); + + let m = empty_module(); + let res = move_bytecode_verifier::verify_module_with_config(&VerifierConfig::unbounded(), &m) + .unwrap_err(); + assert_eq!(res.major_status(), StatusCode::VERIFIER_INVARIANT_VIOLATION); + scenario.teardown(); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/code_unit_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/code_unit_tests.rs new file mode 100644 index 000000000..7db6dfe70 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/code_unit_tests.rs @@ -0,0 +1,98 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::support::dummy_procedure_module; +use move_binary_format::file_format::Bytecode; +use move_bytecode_verifier::meter::DummyMeter; +use move_bytecode_verifier::CodeUnitVerifier; +use move_core_types::vm_status::StatusCode; +use move_vm_config::verifier::VerifierConfig; + +#[test] +fn invalid_fallthrough_br_true() { + let module = dummy_procedure_module(vec![Bytecode::LdFalse, Bytecode::BrTrue(1)]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_FALL_THROUGH + ); +} + +#[test] +fn invalid_fallthrough_br_false() { + let module = dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::BrFalse(1)]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_FALL_THROUGH + ); +} + +// all non-branch instructions should trigger invalid fallthrough; just check one of them +#[test] +fn invalid_fallthrough_non_branch() { + let module = dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::Pop]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_FALL_THROUGH + ); +} + +#[test] +fn valid_fallthrough_branch() { + let module = dummy_procedure_module(vec![Bytecode::Branch(0)]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn valid_fallthrough_ret() { + let module = dummy_procedure_module(vec![Bytecode::Ret]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn valid_fallthrough_abort() { + let module = dummy_procedure_module(vec![Bytecode::LdU64(7), Bytecode::Abort]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_max_number_of_bytecode() { + let mut nops = vec![]; + for _ in 0..u16::MAX - 1 { + nops.push(Bytecode::Nop); + } + nops.push(Bytecode::Ret); + let module = dummy_procedure_module(nops); + + let result = + CodeUnitVerifier::verify_module(&VerifierConfig::unbounded(), &module, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_max_basic_blocks() { + let mut code = (0..17) + .map(|idx| Bytecode::Branch(idx + 1)) + .collect::>(); + code.push(Bytecode::Ret); + let module = dummy_procedure_module(code); + + let result = CodeUnitVerifier::verify_module( + &VerifierConfig { + max_basic_blocks: Some(16), + ..Default::default() + }, + &module, + &mut DummyMeter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TOO_MANY_BASIC_BLOCKS + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs new file mode 100644 index 000000000..b446d72e4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs @@ -0,0 +1,273 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 +use move_binary_format::file_format::{empty_module, CompiledModule, Constant, SignatureToken}; +use move_bytecode_verifier::constants; +use move_core_types::vm_status::StatusCode; +use proptest::prelude::*; + +proptest! { + #[test] + fn valid_generated(module in CompiledModule::valid_strategy(20)) { + prop_assert!(constants::verify_module(&module).is_ok()); + } +} + +#[test] +fn valid_primitives() { + let mut module = empty_module(); + module.constant_pool = vec![ + Constant { + type_: SignatureToken::Bool, + data: vec![0], + }, + Constant { + type_: SignatureToken::U8, + data: vec![0], + }, + Constant { + type_: SignatureToken::U16, + data: vec![0, 0], + }, + Constant { + type_: SignatureToken::U32, + data: vec![0, 0, 0, 0], + }, + Constant { + type_: SignatureToken::U64, + data: vec![0, 0, 0, 0, 0, 0, 0, 0], + }, + Constant { + type_: SignatureToken::U128, + data: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + }, + Constant { + type_: SignatureToken::U256, + data: vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + }, + Constant { + type_: SignatureToken::Address, + data: vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + }, + ]; + assert!(constants::verify_module(&module).is_ok()); +} + +#[test] +fn invalid_primitives() { + malformed(SignatureToken::U8, vec![0, 0]); + malformed(SignatureToken::U16, vec![0, 0, 0, 0]); + malformed(SignatureToken::U32, vec![0, 0, 0]); + malformed(SignatureToken::U64, vec![0]); + malformed(SignatureToken::U128, vec![0]); + malformed(SignatureToken::U256, vec![0, 0]); + let data = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + malformed(SignatureToken::Address, data); +} + +#[test] +fn valid_vectors() { + let double_vec = |item: Vec| -> Vec { + let mut items = vec![2]; + items.extend(item.clone()); + items.extend(item); + items + }; + let large_vec = |item: Vec| -> Vec { + let mut items = vec![0xFF, 0xFF, 3]; + (0..0xFFFF).for_each(|_| items.extend(item.clone())); + items + }; + let mut module = empty_module(); + module.constant_pool = vec![ + // empty + Constant { + type_: tvec(SignatureToken::Bool), + data: vec![0], + }, + Constant { + type_: tvec(tvec(SignatureToken::Bool)), + data: vec![0], + }, + Constant { + type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), + data: vec![0], + }, + Constant { + type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), + data: double_vec(vec![0]), + }, + // small + Constant { + type_: tvec(SignatureToken::Bool), + data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], + }, + Constant { + type_: tvec(SignatureToken::U8), + data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], + }, + // large + Constant { + type_: tvec(SignatureToken::Bool), + data: large_vec(vec![0]), + }, + Constant { + type_: tvec(SignatureToken::U8), + data: large_vec(vec![0]), + }, + Constant { + type_: tvec(SignatureToken::U16), + data: large_vec(vec![0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U32), + data: large_vec(vec![0, 0, 0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U64), + data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U128), + data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U256), + data: large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]), + }, + Constant { + type_: tvec(SignatureToken::Address), + data: large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]), + }, + // double large + Constant { + type_: tvec(tvec(SignatureToken::Bool)), + data: double_vec(large_vec(vec![0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U8)), + data: double_vec(large_vec(vec![0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U16)), + data: double_vec(large_vec(vec![0, 0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U32)), + data: double_vec(large_vec(vec![0, 0, 0, 0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U64)), + data: double_vec(large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U128)), + data: double_vec(large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U256)), + data: double_vec(large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ])), + }, + Constant { + type_: tvec(tvec(SignatureToken::Address)), + data: double_vec(large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ])), + }, + ]; + assert!(constants::verify_module(&module).is_ok()); +} + +#[test] +fn invalid_vectors() { + let double_vec = |item: Vec| -> Vec { + let mut items = vec![2]; + items.extend(item.clone()); + items.extend(item); + items + }; + let too_large_vec = |item: Vec| -> Vec { + let mut items = vec![0xFF, 0xFF, 3]; + (0..(0xFFFF + 1)).for_each(|_| items.extend(item.clone())); + items + }; + // wrong inner + malformed(tvec(SignatureToken::U16), vec![1, 0]); + malformed(tvec(SignatureToken::U32), vec![1, 0]); + malformed(tvec(SignatureToken::U64), vec![1, 0]); + malformed( + tvec(SignatureToken::Address), + vec![ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + ], + ); + // wrong lens + malformed(tvec(SignatureToken::U8), vec![0, 0]); + malformed(tvec(SignatureToken::U8), vec![0, 1]); + malformed(tvec(SignatureToken::U8), vec![2, 1, 1, 1]); + malformed(tvec(tvec(SignatureToken::U8)), double_vec(vec![0, 0])); + // too large + malformed(tvec(SignatureToken::U8), too_large_vec(vec![0])); +} + +#[test] +fn invalid_types() { + invalid_type(SignatureToken::TypeParameter(0), vec![0]); + invalid_type(SignatureToken::TypeParameter(0xFA), vec![0]); + invalid_type(tvec(SignatureToken::TypeParameter(0)), vec![0]); + invalid_type(tvec(SignatureToken::TypeParameter(0xAF)), vec![0]); + + invalid_type(SignatureToken::Signer, vec![0]); + invalid_type(tvec(SignatureToken::Signer), vec![0]); + + // TODO cannot check structs are banned currently. This can be handled by IR and source lang + // tests + // invalid_type(SignatureToken::Struct(StructHandleIndex(0)), vec![0]); +} + +fn tvec(s: SignatureToken) -> SignatureToken { + SignatureToken::Vector(Box::new(s)) +} + +fn malformed(type_: SignatureToken, data: Vec) { + error(type_, data, StatusCode::MALFORMED_CONSTANT_DATA) +} + +fn invalid_type(type_: SignatureToken, data: Vec) { + error(type_, data, StatusCode::INVALID_CONSTANT_TYPE) +} + +fn error(type_: SignatureToken, data: Vec, code: StatusCode) { + let mut module = empty_module(); + module.constant_pool = vec![Constant { type_, data }]; + assert!( + constants::verify_module(&module) + .unwrap_err() + .major_status() + == code + ) +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/control_flow_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/control_flow_tests.rs new file mode 100644 index 000000000..35826cd72 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/control_flow_tests.rs @@ -0,0 +1,240 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::support::dummy_procedure_module; +use move_binary_format::{ + access::ModuleAccess, + errors::PartialVMResult, + file_format::{Bytecode, CompiledModule, FunctionDefinitionIndex, TableIndex}, +}; +use move_bytecode_verifier::{control_flow, meter::DummyMeter}; +use move_core_types::vm_status::StatusCode; +use move_vm_config::verifier::VerifierConfig; + +fn verify_module(verifier_config: &VerifierConfig, module: &CompiledModule) -> PartialVMResult<()> { + for (idx, function_definition) in module + .function_defs() + .iter() + .enumerate() + .filter(|(_, def)| !def.is_native()) + { + let current_function = FunctionDefinitionIndex(idx as TableIndex); + let code = function_definition + .code + .as_ref() + .expect("unexpected native function"); + + control_flow::verify_function( + verifier_config, + module, + current_function, + function_definition, + code, + &mut DummyMeter, + )?; + } + Ok(()) +} + +//************************************************************************************************** +// Simple cases - Copied from code unit verifier +//************************************************************************************************** + +#[test] +fn empty_bytecode() { + let module = dummy_procedure_module(vec![]); + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EMPTY_CODE_UNIT, + ); +} + +#[test] +fn empty_bytecode_v5() { + let mut module = dummy_procedure_module(vec![]); + module.version = 5; + + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EMPTY_CODE_UNIT, + ); +} + +#[test] +fn invalid_fallthrough_br_true() { + let module = dummy_procedure_module(vec![Bytecode::LdFalse, Bytecode::BrTrue(1)]); + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_FALL_THROUGH + ); +} + +#[test] +fn invalid_fallthrough_br_false() { + let module = dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::BrFalse(1)]); + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_FALL_THROUGH + ); +} + +// all non-branch instructions should trigger invalid fallthrough; just check one of them +#[test] +fn invalid_fallthrough_non_branch() { + let module = dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::Pop]); + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_FALL_THROUGH + ); +} + +#[test] +fn valid_fallthrough_branch() { + let module = dummy_procedure_module(vec![Bytecode::Branch(0)]); + let result = verify_module(&Default::default(), &module); + assert!(result.is_ok()); +} + +#[test] +fn valid_fallthrough_ret() { + let module = dummy_procedure_module(vec![Bytecode::Ret]); + let result = verify_module(&Default::default(), &module); + assert!(result.is_ok()); +} + +#[test] +fn valid_fallthrough_abort() { + let module = dummy_procedure_module(vec![Bytecode::LdU64(7), Bytecode::Abort]); + let result = verify_module(&Default::default(), &module); + assert!(result.is_ok()); +} + +#[test] +fn nested_loops_max_depth() { + let module = dummy_procedure_module(vec![ + Bytecode::LdFalse, + Bytecode::LdFalse, + Bytecode::BrFalse(1), + Bytecode::BrFalse(0), + Bytecode::Ret, + ]); + let result = verify_module( + &VerifierConfig { + max_loop_depth: Some(2), + ..VerifierConfig::default() + }, + &module, + ); + assert!(result.is_ok()); +} + +#[test] +fn nested_loops_exceed_max_depth() { + let module = dummy_procedure_module(vec![ + Bytecode::LdFalse, + Bytecode::LdFalse, + Bytecode::LdFalse, + Bytecode::BrFalse(2), + Bytecode::BrFalse(1), + Bytecode::BrFalse(0), + Bytecode::Ret, + ]); + let result = verify_module( + &VerifierConfig { + max_loop_depth: Some(2), + ..VerifierConfig::default() + }, + &module, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::LOOP_MAX_DEPTH_REACHED + ); +} + +#[test] +fn non_loop_backward_jump() { + let module = dummy_procedure_module(vec![ + Bytecode::Branch(2), + Bytecode::Ret, + Bytecode::Branch(1), + ]); + let result = verify_module(&Default::default(), &module); + assert!(result.is_ok()); +} + +#[test] +fn non_loop_backward_jump_v5() { + let mut module = dummy_procedure_module(vec![ + Bytecode::Branch(2), + Bytecode::Ret, + Bytecode::Branch(1), + ]); + + module.version = 5; + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_LOOP_SPLIT, + ); +} + +#[test] +fn irreducible_control_flow_graph() { + let module = dummy_procedure_module(vec![ + Bytecode::LdTrue, + Bytecode::BrTrue(3), + Bytecode::Nop, + Bytecode::LdFalse, + Bytecode::BrFalse(2), + Bytecode::Ret, + ]); + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_LOOP_SPLIT, + ); +} + +#[test] +fn nested_loop_break() { + let module = dummy_procedure_module(vec![ + Bytecode::LdFalse, + Bytecode::LdFalse, + Bytecode::LdFalse, + Bytecode::Branch(7), + Bytecode::BrFalse(2), + Bytecode::BrFalse(1), + Bytecode::BrFalse(0), + Bytecode::Ret, + ]); + let result = verify_module(&Default::default(), &module); + assert!(result.is_ok()); +} + +#[test] +fn nested_loop_break_v5() { + let mut module = dummy_procedure_module(vec![ + Bytecode::LdFalse, + Bytecode::LdFalse, + Bytecode::LdFalse, + Bytecode::Branch(7), + Bytecode::BrFalse(2), + Bytecode::BrFalse(1), + Bytecode::BrFalse(0), + Bytecode::Ret, + ]); + + module.version = 5; + let result = verify_module(&Default::default(), &module); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INVALID_LOOP_BREAK, + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs new file mode 100644 index 000000000..aec512c38 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs @@ -0,0 +1,294 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::file_format::*; +use move_bytecode_verifier::dependencies; +use move_core_types::{ + account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, +}; + +fn mk_script_function_module() -> CompiledModule { + let m = CompiledModule { + version: move_binary_format::file_format_common::VERSION_4, + module_handles: vec![ + // only self module + ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }, + ], + self_module_handle_idx: ModuleHandleIndex(0), + identifiers: vec![ + Identifier::new("M").unwrap(), // Module name + Identifier::new("fn").unwrap(), // Function name + Identifier::new("g_fn").unwrap(), // Generic function name + ], + address_identifiers: vec![ + AccountAddress::ZERO, // Module address + ], + function_handles: vec![ + // fun fn() + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }, + // fun g_fn() + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![AbilitySet::EMPTY], + }, + ], + function_defs: vec![ + // public(script) fun fn() { return; } + FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Visibility::Public, + is_entry: true, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Ret], + }), + }, + // public(script) fun g_fn() { return; } + FunctionDefinition { + function: FunctionHandleIndex(1), + visibility: Visibility::Public, + is_entry: true, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Ret], + }), + }, + ], + signatures: vec![ + Signature(vec![]), // void + ], + struct_defs: vec![], + struct_handles: vec![], + constant_pool: vec![], + metadata: vec![], + field_handles: vec![], + friend_decls: vec![], + struct_def_instantiations: vec![], + function_instantiations: vec![], + field_instantiations: vec![], + }; + move_bytecode_verifier::verify_module_unmetered(&m).unwrap(); + m +} + +fn mk_invoking_module(use_generic: bool, valid: bool) -> CompiledModule { + let call = if use_generic { + Bytecode::CallGeneric(FunctionInstantiationIndex(0)) + } else { + Bytecode::Call(FunctionHandleIndex(1)) + }; + let m = CompiledModule { + version: move_binary_format::file_format_common::VERSION_4, + module_handles: vec![ + // self module + ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }, + // other module + ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(2), + }, + ], + self_module_handle_idx: ModuleHandleIndex(0), + identifiers: vec![ + Identifier::new("Test").unwrap(), // Module name + Identifier::new("test_fn").unwrap(), // test name + Identifier::new("M").unwrap(), // Other Module name + Identifier::new("fn").unwrap(), // Other Function name + Identifier::new("g_fn").unwrap(), // Other Generic function name + ], + address_identifiers: vec![ + AccountAddress::ZERO, // Module address + ], + function_handles: vec![ + // Self::test_fn() + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }, + // 0::M::fn() + FunctionHandle { + module: ModuleHandleIndex(1), + name: IdentifierIndex(3), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }, + // 0::M::g_fn() + FunctionHandle { + module: ModuleHandleIndex(1), + name: IdentifierIndex(4), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![AbilitySet::EMPTY], + }, + ], + // 0::M::g_fn() + function_instantiations: vec![FunctionInstantiation { + handle: FunctionHandleIndex(2), + type_parameters: SignatureIndex(1), + }], + function_defs: vec![ + // fun fn() { return; } + FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Visibility::Public, + is_entry: valid, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![call, Bytecode::Ret], + }), + }, + ], + signatures: vec![ + Signature(vec![]), // void + Signature(vec![SignatureToken::U64]), // u64 + ], + struct_defs: vec![], + struct_handles: vec![], + constant_pool: vec![], + metadata: vec![], + field_handles: vec![], + friend_decls: vec![], + struct_def_instantiations: vec![], + field_instantiations: vec![], + }; + move_bytecode_verifier::verify_module_unmetered(&m).unwrap(); + m +} + +fn mk_invoking_script(use_generic: bool) -> CompiledScript { + let call = if use_generic { + Bytecode::CallGeneric(FunctionInstantiationIndex(0)) + } else { + Bytecode::Call(FunctionHandleIndex(0)) + }; + let s = CompiledScript { + version: move_binary_format::file_format_common::VERSION_4, + module_handles: vec![ + // other module + ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }, + ], + identifiers: vec![ + Identifier::new("M").unwrap(), // Other Module name + Identifier::new("fn").unwrap(), // Other Function name + Identifier::new("g_fn").unwrap(), // Other Generic function name + ], + address_identifiers: vec![ + AccountAddress::ZERO, // Module address + ], + function_handles: vec![ + // 0::M::fn() + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }, + // 0::M::g_fn() + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![AbilitySet::EMPTY], + }, + ], + // 0::M::g_fn() + function_instantiations: vec![FunctionInstantiation { + handle: FunctionHandleIndex(1), + type_parameters: SignatureIndex(1), + }], + type_parameters: vec![], + parameters: SignatureIndex(0), + code: CodeUnit { + locals: SignatureIndex(0), + code: vec![call, Bytecode::Ret], + }, + signatures: vec![ + Signature(vec![]), // void + Signature(vec![SignatureToken::U64]), // u64 + ], + struct_handles: vec![], + constant_pool: vec![], + metadata: vec![], + }; + move_bytecode_verifier::verify_script_unmetered(&s).unwrap(); + s +} + +#[test] + +// tests the deprecated Script visibility logic for < V5 +// tests correct permissible invocation of Script functions +fn deprecated_script_visibility_checks_valid() { + let script_function_module = mk_script_function_module(); + let deps = &[script_function_module]; + + // module uses script functions from script context + let is_valid = true; + let non_generic_call_mod = mk_invoking_module(false, is_valid); + let result = dependencies::verify_module(&non_generic_call_mod, deps); + assert!(result.is_ok()); + + let generic_call_mod = mk_invoking_module(true, is_valid); + let result = dependencies::verify_module(&generic_call_mod, deps); + assert!(result.is_ok()); + + // script uses script functions + let non_generic_call_script = mk_invoking_script(false); + let result = dependencies::verify_script(&non_generic_call_script, deps); + assert!(result.is_ok()); + + let generic_call_script = mk_invoking_script(true); + let result = dependencies::verify_script(&generic_call_script, deps); + assert!(result.is_ok()); +} + +#[test] +// tests the deprecated Script visibility logic for < V5 +// tests correct non-permissible invocation of Script functions +fn deprecated_script_visibility_checks_invalid() { + let script_function_module = mk_script_function_module(); + let deps = &[script_function_module]; + + // module uses script functions from script context + let not_valid = false; + let non_generic_call_mod = mk_invoking_module(false, not_valid); + let result = dependencies::verify_module(&non_generic_call_mod, deps); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CALLED_SCRIPT_VISIBLE_FROM_NON_SCRIPT_VISIBLE, + ); + + let generic_call_mod = mk_invoking_module(true, not_valid); + let result = dependencies::verify_module(&generic_call_mod, deps); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CALLED_SCRIPT_VISIBLE_FROM_NON_SCRIPT_VISIBLE, + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs new file mode 100644 index 000000000..640af70c6 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs @@ -0,0 +1,26 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::file_format::*; +use move_bytecode_verifier::DuplicationChecker; +use proptest::prelude::*; + +#[test] +fn duplicated_friend_decls() { + let mut m = basic_test_module(); + let handle = ModuleHandle { + address: AddressIdentifierIndex::new(0), + name: IdentifierIndex::new(0), + }; + m.friend_decls.push(handle.clone()); + m.friend_decls.push(handle); + DuplicationChecker::verify_module(&m).unwrap_err(); +} + +proptest! { + #[test] + fn valid_duplication(module in CompiledModule::valid_strategy(20)) { + prop_assert!(DuplicationChecker::verify_module(&module).is_ok()); + } +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs new file mode 100644 index 000000000..ef6e43bc1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs @@ -0,0 +1,740 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::file_format::*; +use move_bytecode_verifier::InstructionConsistency; +use move_core_types::{ + account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, +}; + +// Make a Module with 2 structs and 2 resources with one field each, and 2 functions. +// One of the struct/resource and one of the function is generic, the other "normal". +// Also make a test function whose body will be filled by given test cases. +fn make_module() -> CompiledModule { + CompiledModule { + version: move_binary_format::file_format_common::VERSION_MAX, + module_handles: vec![ + // only self module + ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }, + ], + self_module_handle_idx: ModuleHandleIndex(0), + identifiers: vec![ + Identifier::new("M").unwrap(), // Module name + Identifier::new("S").unwrap(), // Struct name + Identifier::new("GS").unwrap(), // Generic struct name + Identifier::new("R").unwrap(), // Resource name + Identifier::new("GR").unwrap(), // Generic resource name + Identifier::new("f").unwrap(), // Field name + Identifier::new("fn").unwrap(), // Function name + Identifier::new("g_fn").unwrap(), // Generic function name + Identifier::new("test_fn").unwrap(), // Test function name + ], + address_identifiers: vec![ + AccountAddress::ZERO, // Module address + ], + struct_handles: vec![ + StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + abilities: AbilitySet::PRIMITIVES, + type_parameters: vec![], + }, + StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + abilities: AbilitySet::PRIMITIVES, + type_parameters: vec![StructTypeParameter { + constraints: AbilitySet::PRIMITIVES, + is_phantom: false, + }], + }, + StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(3), + abilities: AbilitySet::EMPTY | Ability::Key, + type_parameters: vec![], + }, + StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(4), + abilities: AbilitySet::EMPTY | Ability::Key, + type_parameters: vec![StructTypeParameter { + constraints: AbilitySet::PRIMITIVES, + is_phantom: false, + }], + }, + ], + struct_defs: vec![ + // struct S { f: u64 } + StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::U64), + }]), + }, + // struct GS { f: T } + StructDefinition { + struct_handle: StructHandleIndex(1), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::TypeParameter(0)), + }]), + }, + // struct R has key { f: u64 } + StructDefinition { + struct_handle: StructHandleIndex(2), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::U64), + }]), + }, + // struct GR has key { f: T } + StructDefinition { + struct_handle: StructHandleIndex(3), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::TypeParameter(0)), + }]), + }, + ], + function_handles: vec![ + // fun fn() + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(6), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }, + // fun g_fn() + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(7), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![AbilitySet::EMPTY | Ability::Key], + }, + // fun test_fn(Sender) + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(8), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }, + ], + function_defs: vec![ + // public fun fn() { return; } + FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Visibility::Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Ret], + }), + }, + // fun g_fn() { return; } + FunctionDefinition { + function: FunctionHandleIndex(1), + visibility: Visibility::Private, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Ret], + }), + }, + // fun test_fn() { ... } - tests will fill up the code + FunctionDefinition { + function: FunctionHandleIndex(2), + visibility: Visibility::Private, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![], + }), + }, + ], + signatures: vec![ + Signature(vec![]), // void + Signature(vec![SignatureToken::Signer]), // Signer + ], + constant_pool: vec![ + // an address + Constant { + type_: SignatureToken::Address, + data: AccountAddress::random().to_vec(), + }, + ], + metadata: vec![], + field_handles: vec![], + friend_decls: vec![], + struct_def_instantiations: vec![], + function_instantiations: vec![], + field_instantiations: vec![], + } +} + +#[test] +fn generic_call_to_non_generic_func() { + let mut module = make_module(); + // bogus `CallGeneric fn()` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::CallGeneric(FunctionInstantiationIndex(0)), + Bytecode::Ret, + ], + }); + module.function_instantiations.push(FunctionInstantiation { + handle: FunctionHandleIndex(0), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("CallGeneric to non generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_call_to_generic_func() { + let mut module = make_module(); + // bogus `Call g_fn()` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + }); + let err = InstructionConsistency::verify_module(&module) + .expect_err("Call to generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_pack_on_non_generic_struct() { + let mut module = make_module(); + // bogus `PackGeneric S` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(0), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("PackGeneric to non generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_pack_on_generic_struct() { + let mut module = make_module(); + // bogus `Pack GS` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::Pack(StructDefinitionIndex(1)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + let err = InstructionConsistency::verify_module(&module) + .expect_err("Pack to generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_unpack_on_non_generic_struct() { + let mut module = make_module(); + // bogus `UnpackGeneric S` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::UnpackGeneric(StructDefInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(0), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("UnpackGeneric to non generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_unpack_on_generic_struct() { + let mut module = make_module(); + // bogus `Unpack GS` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::Unpack(StructDefinitionIndex(1)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(1), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("Unpack to generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_mut_borrow_field_on_non_generic_struct() { + let mut module = make_module(); + // bogus `MutBorrowFieldGeneric S.t` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module.field_instantiations.push(FieldInstantiation { + handle: FieldHandleIndex(0), + type_parameters: SignatureIndex(2), + }); + module.field_handles.push(FieldHandle { + owner: StructDefinitionIndex(0), + field: 0, + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MutBorrowFieldGeneric to non generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_mut_borrow_field_on_generic_struct() { + let mut module = make_module(); + // bogus `MutBorrowField GS.f` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::MutBorrowField(FieldHandleIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(1), + type_parameters: SignatureIndex(2), + }); + module.field_handles.push(FieldHandle { + owner: StructDefinitionIndex(1), + field: 0, + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MutBorrowField to generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_borrow_field_on_non_generic_struct() { + let mut module = make_module(); + // bogus `ImmBorrowFieldGeneric S.f` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module.field_instantiations.push(FieldInstantiation { + handle: FieldHandleIndex(0), + type_parameters: SignatureIndex(2), + }); + module.field_handles.push(FieldHandle { + owner: StructDefinitionIndex(0), + field: 0, + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("ImmBorrowFieldGeneric to non generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_borrow_field_on_generic_struct() { + let mut module = make_module(); + // bogus `ImmBorrowField GS.f` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdU64(10), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::ImmBorrowField(FieldHandleIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(1), + type_parameters: SignatureIndex(2), + }); + module.field_handles.push(FieldHandle { + owner: StructDefinitionIndex(1), + field: 0, + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("ImmBorrowField to generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_mut_borrow_global_to_non_generic_struct() { + let mut module = make_module(); + // bogus `MutBorrowGlobalGeneric R` + module.function_defs[2] + .acquires_global_resources + .push(StructDefinitionIndex(2)); + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::MutBorrowGlobalGeneric(StructDefInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(2), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MutBorrowGlobalGeneric to non generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_mut_borrow_global_to_generic_struct() { + let mut module = make_module(); + // bogus `MutBorrowGlobal GR` + module.function_defs[2] + .acquires_global_resources + .push(StructDefinitionIndex(3)); + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::MutBorrowGlobal(StructDefinitionIndex(3)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MutBorrowGlobal to generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_immut_borrow_global_to_non_generic_struct() { + let mut module = make_module(); + // bogus `ImmBorrowGlobalGeneric R` + module.function_defs[2] + .acquires_global_resources + .push(StructDefinitionIndex(2)); + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::ImmBorrowGlobalGeneric(StructDefInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(2), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("ImmBorrowGlobalGeneric to non generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_immut_borrow_global_to_generic_struct() { + let mut module = make_module(); + // bogus `ImmBorrowGlobal GR` + module.function_defs[2] + .acquires_global_resources + .push(StructDefinitionIndex(3)); + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::ImmBorrowGlobal(StructDefinitionIndex(3)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + let err = InstructionConsistency::verify_module(&module) + .expect_err("ImmBorrowGlobal to generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_exists_to_non_generic_struct() { + let mut module = make_module(); + // bogus `ExistsGeneric R` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::ExistsGeneric(StructDefInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(2), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("ExistsGeneric to non generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_exists_to_generic_struct() { + let mut module = make_module(); + // bogus `Exists GR` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::Exists(StructDefinitionIndex(3)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + let err = InstructionConsistency::verify_module(&module) + .expect_err("Exists to generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_move_from_to_non_generic_struct() { + let mut module = make_module(); + // bogus `MoveFromGeneric R` + module.function_defs[2] + .acquires_global_resources + .push(StructDefinitionIndex(2)); + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::MoveFromGeneric(StructDefInstantiationIndex(0)), + Bytecode::Unpack(StructDefinitionIndex(2)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(2), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MoveFromGeneric to non generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_move_from_to_generic_struct() { + let mut module = make_module(); + // bogus `MoveFrom GR` + module.function_defs[2] + .acquires_global_resources + .push(StructDefinitionIndex(3)); + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::LdConst(ConstantPoolIndex(0)), + Bytecode::MoveFrom(StructDefinitionIndex(3)), + Bytecode::UnpackGeneric(StructDefInstantiationIndex(0)), + Bytecode::Pop, + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(3), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MoveFrom to generic function must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn generic_move_to_on_non_generic_struct() { + let mut module = make_module(); + // bogus `MoveToGeneric R` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::MoveLoc(0), + Bytecode::LdU64(10), + Bytecode::Pack(StructDefinitionIndex(2)), + Bytecode::MoveToGeneric(StructDefInstantiationIndex(0)), + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(2), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MoveToGeneric to non generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} + +#[test] +fn non_generic_move_to_on_generic_struct() { + let mut module = make_module(); + // bogus `MoveTo GR` + module.function_defs[2].code = Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![ + Bytecode::MoveLoc(0), + Bytecode::LdU64(10), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::MoveTo(StructDefinitionIndex(3)), + Bytecode::Ret, + ], + }); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(3), + type_parameters: SignatureIndex(2), + }); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let err = InstructionConsistency::verify_module(&module) + .expect_err("MoveTo to generic struct must fail"); + assert_eq!( + err.major_status(), + StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs new file mode 100644 index 000000000..ab7e09e49 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs @@ -0,0 +1,159 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::unit_tests::production_config; +use move_binary_format::file_format::{ + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, + IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + Visibility::Public, +}; +use move_bytecode_verifier::meter::BoundMeter; +use move_core_types::{identifier::Identifier, vm_status::StatusCode}; + +const NUM_LOCALS: u8 = 64; +const NUM_CALLS: u16 = 77; +const NUM_FUNCTIONS: u16 = 177; + +fn get_nested_vec_type(len: usize) -> SignatureToken { + let mut ret = SignatureToken::Bool; + for _ in 0..len { + ret = SignatureToken::Vector(Box::new(ret)); + } + ret +} + +#[test] +fn test_large_types() { + // See also: github.com/aptos-labs/aptos-core/security/advisories/GHSA-37qw-jfpw-8899 + let mut m = empty_module(); + + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::Reference(Box::new(get_nested_vec_type(64)))) + .take(NUM_LOCALS as usize) + .collect(), + )); + + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + }), + }); + + // returns_vecs + m.identifiers.push(Identifier::new("returns_vecs").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(0), + return_: SignatureIndex(1), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(1), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + }), + }); + + // takes_and_returns_vecs + m.identifiers + .push(Identifier::new("takes_and_returns_vecs").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + parameters: SignatureIndex(1), + return_: SignatureIndex(1), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(2), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + }), + }); + + // takes_vecs + m.identifiers.push(Identifier::new("takes_vecs").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(3), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(3), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Ret], + }), + }); + + // other fcts + for i in 0..NUM_FUNCTIONS { + m.identifiers + .push(Identifier::new(format!("f{}", i)).unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(i + 4), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(i + 4), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![], + }), + }); + + let code = &mut m.function_defs[i as usize + 4].code.as_mut().unwrap().code; + code.clear(); + code.push(Bytecode::Call(FunctionHandleIndex(1))); + for _ in 0..NUM_CALLS { + code.push(Bytecode::Call(FunctionHandleIndex(2))); + } + code.push(Bytecode::Call(FunctionHandleIndex(3))); + code.push(Bytecode::Ret); + } + + let config = production_config(); + let mut meter = BoundMeter::new(&config); + let result = move_bytecode_verifier::verify_module_with_config_for_test( + "test_large_types", + &config, + &m, + &mut meter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CONSTRAINT_NOT_SATISFIED, + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs new file mode 100644 index 000000000..7da5767ee --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs @@ -0,0 +1,894 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::unit_tests::production_config; +use move_binary_format::file_format::*; +use move_bytecode_verifier::{ + limits::LimitsVerifier, meter::DummyMeter, verify_module_with_config_for_test, +}; +use move_core_types::{ + account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, +}; +use move_vm_config::verifier::{VerifierConfig, DEFAULT_MAX_IDENTIFIER_LENGTH}; + +#[test] +fn test_function_handle_type_instantiation() { + let mut m = basic_test_module(); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex::new(0), + name: IdentifierIndex::new(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: std::iter::repeat(AbilitySet::ALL).take(10).collect(), + }); + + assert_eq!( + LimitsVerifier::verify_module( + &VerifierConfig { + max_generic_instantiation_length: Some(9), + ..Default::default() + }, + &m + ) + .unwrap_err() + .major_status(), + StatusCode::TOO_MANY_TYPE_PARAMETERS + ); + + let mut s = basic_test_script(); + s.function_handles.push(FunctionHandle { + module: ModuleHandleIndex::new(0), + name: IdentifierIndex::new(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: std::iter::repeat(AbilitySet::ALL).take(10).collect(), + }); + + assert_eq!( + LimitsVerifier::verify_script( + &VerifierConfig { + max_generic_instantiation_length: Some(9), + ..Default::default() + }, + &s + ) + .unwrap_err() + .major_status(), + StatusCode::TOO_MANY_TYPE_PARAMETERS + ); +} + +#[test] +fn test_struct_handle_type_instantiation() { + let mut m = basic_test_module(); + m.struct_handles.push(StructHandle { + module: ModuleHandleIndex::new(0), + name: IdentifierIndex::new(0), + abilities: AbilitySet::ALL, + type_parameters: std::iter::repeat(StructTypeParameter { + constraints: AbilitySet::ALL, + is_phantom: false, + }) + .take(10) + .collect(), + }); + + assert_eq!( + LimitsVerifier::verify_module( + &VerifierConfig { + max_generic_instantiation_length: Some(9), + ..Default::default() + }, + &m + ) + .unwrap_err() + .major_status(), + StatusCode::TOO_MANY_TYPE_PARAMETERS + ); + + let mut s = basic_test_script(); + s.struct_handles.push(StructHandle { + module: ModuleHandleIndex::new(0), + name: IdentifierIndex::new(0), + abilities: AbilitySet::ALL, + type_parameters: std::iter::repeat(StructTypeParameter { + constraints: AbilitySet::ALL, + is_phantom: false, + }) + .take(10) + .collect(), + }); + + assert_eq!( + LimitsVerifier::verify_script( + &VerifierConfig { + max_generic_instantiation_length: Some(9), + ..Default::default() + }, + &s + ) + .unwrap_err() + .major_status(), + StatusCode::TOO_MANY_TYPE_PARAMETERS + ); +} + +#[test] +fn test_function_handle_parameters() { + let mut m = basic_test_module(); + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::Bool).take(10).collect(), + )); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex::new(0), + name: IdentifierIndex::new(0), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + + assert_eq!( + LimitsVerifier::verify_module( + &VerifierConfig { + max_function_parameters: Some(9), + ..Default::default() + }, + &m + ) + .unwrap_err() + .major_status(), + StatusCode::TOO_MANY_PARAMETERS + ); + + let mut s = basic_test_script(); + s.signatures.push(Signature( + std::iter::repeat(SignatureToken::Bool).take(10).collect(), + )); + s.function_handles.push(FunctionHandle { + module: ModuleHandleIndex::new(0), + name: IdentifierIndex::new(0), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + + assert_eq!( + LimitsVerifier::verify_script( + &VerifierConfig { + max_function_parameters: Some(9), + ..Default::default() + }, + &s + ) + .unwrap_err() + .major_status(), + StatusCode::TOO_MANY_PARAMETERS + ); +} + +#[test] +fn big_vec_unpacks() { + const N_TYPE_PARAMS: usize = 16; + let mut st = SignatureToken::Vector(Box::new(SignatureToken::U8)); + let type_params = vec![st; N_TYPE_PARAMS]; + st = SignatureToken::StructInstantiation(StructHandleIndex(0), type_params); + const N_VEC_PUSH: u16 = 1000; + let mut code = vec![]; + // 1. CopyLoc: ... -> ... st + // 2. VecPack: ... st -> ... Vec + // 3. VecUnpack: ... Vec -> ... st, st, st, ... st + for _ in 0..N_VEC_PUSH { + code.push(Bytecode::CopyLoc(0)); + code.push(Bytecode::VecPack(SignatureIndex(1), 1)); + code.push(Bytecode::VecUnpack(SignatureIndex(1), 1 << 15)); + } + // 1. VecPack: ... st, st, st, ... st -> ... Vec + // 2. Pop: ... Vec -> ... + for _ in 0..N_VEC_PUSH { + code.push(Bytecode::VecPack(SignatureIndex(1), 1 << 15)); + code.push(Bytecode::Pop); + } + code.push(Bytecode::Ret); + let type_param_constraints = StructTypeParameter { + constraints: AbilitySet::EMPTY, + is_phantom: false, + }; + let module = CompiledModule { + version: 5, + self_module_handle_idx: ModuleHandleIndex(0), + module_handles: vec![ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }], + struct_handles: vec![StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + abilities: AbilitySet::ALL, + type_parameters: vec![type_param_constraints; N_TYPE_PARAMS], + }], + function_handles: vec![FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }], + field_handles: vec![], + friend_decls: vec![], + struct_def_instantiations: vec![], + function_instantiations: vec![], + field_instantiations: vec![], + signatures: vec![Signature(vec![]), Signature(vec![st])], + identifiers: vec![ + Identifier::new("f").unwrap(), + Identifier::new("generic_struct").unwrap(), + ], + address_identifiers: vec![AccountAddress::ONE], + constant_pool: vec![], + metadata: vec![], + struct_defs: vec![StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Native, + }], + function_defs: vec![FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Visibility::Public, + is_entry: true, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code, + }), + }], + }; + + // save module and verify that it can ser/de + let mut mvbytes = vec![]; + module.serialize(&mut mvbytes).unwrap(); + let module = CompiledModule::deserialize_with_defaults(&mvbytes).unwrap(); + + let res = verify_module_with_config_for_test( + "big_vec_unpacks", + &VerifierConfig { + max_loop_depth: Some(5), + max_generic_instantiation_length: Some(32), + max_function_parameters: Some(128), + max_basic_blocks: Some(1024), + max_push_size: Some(10000), + ..Default::default() + }, + &module, + &mut DummyMeter, + ); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::VALUE_STACK_PUSH_OVERFLOW + ); +} + +const MAX_STRUCTS: usize = 200; +const MAX_FIELDS: usize = 30; +const MAX_FUNCTIONS: usize = 1000; + +#[test] +fn max_struct_test() { + let config = VerifierConfig { + max_struct_definitions: Some(MAX_STRUCTS), + max_fields_in_struct: Some(MAX_FIELDS), + max_function_definitions: Some(MAX_FUNCTIONS), + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, 0); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + multi_struct(&mut module, 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS / 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS * 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS + 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, + ); +} + +#[test] +fn max_fields_test() { + let config = VerifierConfig { + max_struct_definitions: Some(MAX_STRUCTS), + max_fields_in_struct: Some(MAX_FIELDS), + max_function_definitions: Some(MAX_FUNCTIONS), + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, 1); + multi_fields(&mut module, MAX_FIELDS / 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, 10); + multi_fields(&mut module, MAX_FIELDS - 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, 50); + multi_fields(&mut module, MAX_FIELDS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, 100); + multi_fields(&mut module, MAX_FIELDS + 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FIELD_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, 2); + multi_fields(&mut module, MAX_FIELDS * 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FIELD_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, 50); + multi_fields_except_one(&mut module, 0, 2, MAX_FIELDS + 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FIELD_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, 20); + multi_fields_except_one(&mut module, 19, MAX_FIELDS, MAX_FIELDS + 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FIELD_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, 100); + multi_fields_except_one(&mut module, 50, 1, MAX_FIELDS * 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FIELD_DEFINITIONS_REACHED, + ); +} + +#[test] +fn max_functions_test() { + let config = VerifierConfig { + max_struct_definitions: Some(MAX_STRUCTS), + max_fields_in_struct: Some(MAX_FIELDS), + max_function_definitions: Some(MAX_FUNCTIONS), + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, 1); + multi_functions(&mut module, 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, 10); + multi_functions(&mut module, MAX_FUNCTIONS / 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, 5); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, 5); + multi_functions(&mut module, MAX_FUNCTIONS - 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, 5); + multi_functions(&mut module, MAX_FUNCTIONS + 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_functions(&mut module, MAX_FUNCTIONS * 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, + ); +} + +#[test] +fn max_mixed_config_test() { + let config = VerifierConfig { + max_struct_definitions: Some(MAX_STRUCTS), + max_fields_in_struct: Some(MAX_FIELDS), + max_function_definitions: Some(MAX_FUNCTIONS), + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + + let config = VerifierConfig { + max_function_definitions: None, + max_struct_definitions: None, + max_fields_in_struct: None, + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, 1); + multi_fields(&mut module, 1); + multi_functions(&mut module, 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS * 2); + multi_fields(&mut module, MAX_FIELDS * 2); + multi_functions(&mut module, MAX_FUNCTIONS * 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS + 1); + multi_fields(&mut module, MAX_FIELDS + 1); + multi_functions(&mut module, MAX_FUNCTIONS + 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + + let config = VerifierConfig { + max_struct_definitions: Some(MAX_STRUCTS), + max_fields_in_struct: Some(MAX_FIELDS), + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS + 10); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS * 3); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS * 2); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS + 1); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS * 2); + multi_functions(&mut module, MAX_FUNCTIONS * 3); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FIELD_DEFINITIONS_REACHED, + ); + + let config = VerifierConfig { + max_struct_definitions: Some(MAX_STRUCTS), + max_function_definitions: Some(MAX_FUNCTIONS), + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS + 1); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS * 3); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS * 2); + multi_fields(&mut module, MAX_FIELDS * 3); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS * 2); + multi_functions(&mut module, MAX_FUNCTIONS * 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, + ); + + let config = VerifierConfig { + max_fields_in_struct: Some(MAX_FIELDS), + max_function_definitions: Some(MAX_FUNCTIONS), + ..Default::default() + }; + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS * 3); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS + 1); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!(res, Ok(())); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS + 1); + multi_fields(&mut module, MAX_FIELDS * 3); + multi_functions(&mut module, MAX_FUNCTIONS); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FIELD_DEFINITIONS_REACHED, + ); + let mut module = leaf_module("M"); + multi_struct(&mut module, MAX_STRUCTS * 2); + multi_fields(&mut module, MAX_FIELDS); + multi_functions(&mut module, MAX_FUNCTIONS * 2); + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, + ); +} + +#[test] +fn max_identifier_len() { + let config = production_config(); + let max_ident = "z".repeat( + config + .max_idenfitier_len + .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize, + ); + let good_module = leaf_module(&max_ident); + + let res = LimitsVerifier::verify_module(&config, &good_module); + assert!(res.is_ok()); + + let config = production_config(); + let max_ident = "z".repeat( + (config + .max_idenfitier_len + .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize) + / 2, + ); + let good_module = leaf_module(&max_ident); + + let res = LimitsVerifier::verify_module(&config, &good_module); + assert!(res.is_ok()); + + let over_max_ident = "z".repeat( + 1 + config + .max_idenfitier_len + .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize, + ); + let bad_module = leaf_module(&over_max_ident); + let res = LimitsVerifier::verify_module(&config, &bad_module); + + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::IDENTIFIER_TOO_LONG, + ); + + let over_max_ident = "zx".repeat( + 1 + config + .max_idenfitier_len + .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize, + ); + let bad_module = leaf_module(&over_max_ident); + let res = LimitsVerifier::verify_module(&config, &bad_module); + + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::IDENTIFIER_TOO_LONG, + ); +} + +#[test] +fn max_vec_len() { + let config = VerifierConfig { + max_constant_vector_len: Some(0xFFFF - 1), + ..Default::default() + }; + let double_vec = |item: Vec| -> Vec { + let mut items = vec![2]; + items.extend(item.clone()); + items.extend(item); + items + }; + let large_vec = |item: Vec| -> Vec { + let mut items = vec![0xFF, 0xFF, 3]; + (0..0xFFFF).for_each(|_| items.extend(item.clone())); + items + }; + fn tvec(s: SignatureToken) -> SignatureToken { + SignatureToken::Vector(Box::new(s)) + } + + let mut module = empty_module(); + module.constant_pool = vec![Constant { + type_: tvec(SignatureToken::Bool), + data: large_vec(vec![0]), + }]; + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::TOO_MANY_VECTOR_ELEMENTS, + ); + + let mut module = empty_module(); + module.constant_pool = vec![Constant { + type_: tvec(SignatureToken::U256), + data: large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ]), + }]; + let res = LimitsVerifier::verify_module(&config, &module); + assert_eq!( + res.unwrap_err().major_status(), + StatusCode::TOO_MANY_VECTOR_ELEMENTS, + ); + + let config = VerifierConfig { + max_constant_vector_len: Some(0xFFFF), + ..Default::default() + }; + + let mut module = empty_module(); + module.constant_pool = vec![ + // empty + Constant { + type_: tvec(SignatureToken::Bool), + data: vec![0], + }, + Constant { + type_: tvec(tvec(SignatureToken::Bool)), + data: vec![0], + }, + Constant { + type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), + data: vec![0], + }, + Constant { + type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), + data: double_vec(vec![0]), + }, + // small + Constant { + type_: tvec(SignatureToken::Bool), + data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], + }, + Constant { + type_: tvec(SignatureToken::U8), + data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], + }, + // large + Constant { + type_: tvec(SignatureToken::Bool), + data: large_vec(vec![0]), + }, + Constant { + type_: tvec(SignatureToken::U8), + data: large_vec(vec![0]), + }, + Constant { + type_: tvec(SignatureToken::U16), + data: large_vec(vec![0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U32), + data: large_vec(vec![0, 0, 0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U64), + data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U128), + data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + }, + Constant { + type_: tvec(SignatureToken::U256), + data: large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]), + }, + Constant { + type_: tvec(SignatureToken::Address), + data: large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]), + }, + // double large + Constant { + type_: tvec(tvec(SignatureToken::Bool)), + data: double_vec(large_vec(vec![0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U8)), + data: double_vec(large_vec(vec![0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U16)), + data: double_vec(large_vec(vec![0, 0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U32)), + data: double_vec(large_vec(vec![0, 0, 0, 0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U64)), + data: double_vec(large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U128)), + data: double_vec(large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ])), + }, + Constant { + type_: tvec(tvec(SignatureToken::U256)), + data: double_vec(large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ])), + }, + Constant { + type_: tvec(tvec(SignatureToken::Address)), + data: double_vec(large_vec(vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ])), + }, + ]; + let res = LimitsVerifier::verify_module(&config, &module); + + assert!(res.is_ok()); +} + +fn multi_struct(module: &mut CompiledModule, count: usize) { + for i in 0..count { + module + .identifiers + .push(Identifier::new(format!("A_{}", i)).unwrap()); + module.struct_handles.push(StructHandle { + module: module.self_module_handle_idx, + name: IdentifierIndex((module.identifiers.len() - 1) as u16), + abilities: AbilitySet::EMPTY, + type_parameters: vec![], + }); + module.struct_defs.push(StructDefinition { + struct_handle: StructHandleIndex((module.struct_handles.len() - 1) as u16), + field_information: StructFieldInformation::Declared(vec![]), + }); + } +} + +fn multi_fields(module: &mut CompiledModule, count: usize) { + for def in &mut module.struct_defs { + let mut fields = vec![]; + for i in 0..count { + module + .identifiers + .push(Identifier::new(format!("f_{}", i)).unwrap()); + fields.push(FieldDefinition { + name: Default::default(), + signature: TypeSignature(SignatureToken::U8), + }); + } + def.field_information = StructFieldInformation::Declared(fields); + } +} + +fn multi_fields_except_one(module: &mut CompiledModule, idx: usize, count: usize, one: usize) { + for (struct_idx, def) in module.struct_defs.iter_mut().enumerate() { + let mut fields = vec![]; + let count = if struct_idx == idx { one } else { count }; + for i in 0..count { + module + .identifiers + .push(Identifier::new(format!("f_{}", i)).unwrap()); + fields.push(FieldDefinition { + name: Default::default(), + signature: TypeSignature(SignatureToken::U8), + }); + } + def.field_information = StructFieldInformation::Declared(fields); + } +} + +fn multi_functions(module: &mut CompiledModule, count: usize) { + module.signatures.push(Signature(vec![])); + for i in 0..count { + module + .identifiers + .push(Identifier::new(format!("func_{}", i)).unwrap()); + module.function_handles.push(FunctionHandle { + module: module.self_module_handle_idx, + name: IdentifierIndex((module.identifiers.len() - 1) as u16), + parameters: SignatureIndex((module.signatures.len() - 1) as u16), + return_: SignatureIndex((module.signatures.len() - 1) as u16), + type_parameters: vec![], + }); + module.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex((module.function_handles.len() - 1) as u16), + visibility: Visibility::Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex((module.signatures.len() - 1) as u16), + code: vec![Bytecode::Ret], + }), + }); + } +} + +fn leaf_module(name: &str) -> CompiledModule { + let mut module = empty_module(); + module.identifiers[0] = Identifier::new(name).unwrap(); + module.address_identifiers[0] = AccountAddress::ONE; + module +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/locals.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/locals.rs new file mode 100644 index 000000000..d39afa6d0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/locals.rs @@ -0,0 +1,124 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::unit_tests::production_config; +use move_binary_format::file_format::{ + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, + IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + Visibility::Public, +}; +use move_bytecode_verifier::meter::BoundMeter; +use move_core_types::{identifier::Identifier, vm_status::StatusCode}; + +#[test] +fn test_locals() { + // See also: github.com/aptos-labs/aptos-core/security/advisories/GHSA-jjqw-f9pc-525j + let mut m = empty_module(); + + const MAX_BASIC_BLOCKS: u16 = 1024; + const MAX_LOCALS: u8 = 255; + const NUM_FUNCTIONS: u16 = 16; + + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Public, + is_entry: true, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Ret], + }), + }); + + // signature of locals in f1..f + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::U8) + .take(MAX_LOCALS as usize) + .collect(), + )); + + m.identifiers.push(Identifier::new("pwn").unwrap()); + + // create returns_bool_and_u64 + m.signatures + .push(Signature(vec![SignatureToken::Bool, SignatureToken::U8])); + m.identifiers + .push(Identifier::new("returns_bool_and_u64").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(0), + return_: SignatureIndex(2), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(1), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::LdTrue, Bytecode::LdU8(0), Bytecode::Ret], + }), + }); + + // create other functions + for i in 1..(NUM_FUNCTIONS + 1) { + m.identifiers + .push(Identifier::new(format!("f{}", i)).unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(i + 1), // the +1 accounts for returns_bool_and_u64 + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(i + 1), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(1), + code: vec![], + }), + }); + + let code = &mut m.function_defs[i as usize + 1].code.as_mut().unwrap().code; + + for _ in 0..(MAX_BASIC_BLOCKS / 2 - MAX_LOCALS as u16 - 3) { + code.push(Bytecode::LdTrue); + code.push(Bytecode::BrTrue((code.len() + 2) as u16)); + code.push(Bytecode::Ret); + code.push(Bytecode::LdTrue); + code.push(Bytecode::BrTrue(0)); + } + for i in 0..MAX_LOCALS { + code.push(Bytecode::Call(FunctionHandleIndex(1))); // calls returns_bool_and_u64 + code.push(Bytecode::StLoc(i as u8)); // i'th local is now available for the first time + code.push(Bytecode::BrTrue(0)); + } + code.push(Bytecode::Ret); + } + + let config = production_config(); + let mut meter = BoundMeter::new(&config); + let result = move_bytecode_verifier::verify_module_with_config_for_test( + "test_locals", + &config, + &m, + &mut meter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CONSTRAINT_NOT_SATISFIED + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs new file mode 100644 index 000000000..819b94127 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs @@ -0,0 +1,391 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::{control_flow_graph::VMControlFlowGraph, file_format::Bytecode}; +use move_bytecode_verifier::loop_summary::{LoopPartition, LoopSummary}; + +macro_rules! assert_node { + ( $summary:ident, $node:expr ; $block:expr, $preds:expr, $descs:expr, $backs:expr ) => { + let (s, n) = (&$summary, $node); + assert_eq!(s.block(n), $block, "Block"); + + let descs = $descs; + for d in descs { + assert!(s.is_descendant(n, *d), "{:?} -> {:?}", n, d) + } + + assert_eq!(s.pred_edges(n), $preds, "Predecessor Edges"); + assert_eq!(s.back_edges(n), $backs, "Back Edges"); + }; +} + +#[test] +fn linear_summary() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ Nop, + /* */ Branch(2), + /* B2, L1 */ Nop, + /* */ Branch(4), + /* B4, L2 */ Ret, + ])) + }; + + let n: Vec<_> = summary.preorder().collect(); + + assert_eq!(n.len(), 3); + + assert_node!( + summary, n[0]; + /* block */ 0, + /* preds */ &[], + /* descs */ &[n[1], n[2]], + /* backs */ &[] + ); + + assert_node!( + summary, n[1]; + /* block */ 2, + /* preds */ &[n[0]], + /* descs */ &[n[2]], + /* backs */ &[] + ); + + assert_node!( + summary, n[2]; + /* block */ 4, + /* preds */ &[n[1]], + /* descs */ &[], + /* backs */ &[] + ); +} + +#[test] +fn non_loop_back_branch_summary() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ Nop, + /* */ Branch(3), + /* B2, L2 */ Ret, + /* B3, L1 */ Branch(2), + ])) + }; + + let n: Vec<_> = summary.preorder().collect(); + + assert_eq!(n.len(), 3); + + assert_node!( + summary, n[0]; + /* block */ 0, + /* preds */ &[], + /* descs */ &[n[1], n[2]], + /* backs */ &[] + ); + + assert_node!( + summary, n[1]; + /* block */ 3, + /* preds */ &[n[0]], + /* descs */ &[n[2]], + /* backs */ &[] + ); + + assert_node!( + summary, n[2]; + /* block */ 2, + /* preds */ &[n[1]], + /* descs */ &[], + /* backs */ &[] + ); +} + +#[test] +fn branching_summary() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(3), + /* B2, L2 */ Nop, + /* B3, L1 */ Ret, + ])) + }; + + let n: Vec<_> = summary.preorder().collect(); + + assert_eq!(n.len(), 3); + + assert_node!( + summary, n[0]; + /* block */ 0, + /* preds */ &[], + /* descs */ &[n[1], n[2]], + /* backs */ &[] + ); + + assert_node!( + summary, n[1]; + /* block */ 3, + /* preds */ &[n[0], n[2]], + /* descs */ &[], + /* backs */ &[] + ); + + assert_node!( + summary, n[2]; + /* block */ 2, + /* preds */ &[n[0]], + /* descs */ &[], + /* backs */ &[] + ); + + // Although L2 -> L1 is an edge in the CFG, it's not an edge in the DFST, so L2 is said to have + // no descendants. + assert!(!summary.is_descendant(n[2], n[1])); +} + +#[test] +fn looping_summary() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(4), + /* B2, L2 */ Nop, + /* */ Branch(0), + /* B4, L1 */ Ret, + ])) + }; + + let n: Vec<_> = summary.preorder().collect(); + + assert_eq!(n.len(), 3); + + assert_node!( + summary, n[0]; + /* block */ 0, + /* preds */ &[], + /* descs */ &[n[1], n[2]], + /* backs */ &[n[2]] + ); + + assert_node!( + summary, n[1]; + /* block */ 4, + /* preds */ &[n[0]], + /* descs */ &[], + /* backs */ &[] + ); + + assert_node!( + summary, n[2]; + /* block */ 2, + /* preds */ &[n[0]], + /* descs */ &[], + /* backs */ &[] + ); +} + +#[test] +fn branches_in_loops_summary() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(3), + /* B2, L3 */ Nop, + /* B3, L1 */ LdFalse, + /* */ BrFalse(0), + /* B5, L2 */ Ret, + ])) + }; + + let n: Vec<_> = summary.preorder().collect(); + + assert_eq!(n.len(), 4); + + assert_node!( + summary, n[0]; + /* block */ 0, + /* preds */ &[], + /* descs */ &[n[1], n[2], n[3]], + /* backs */ &[n[1]] + ); + + assert_node!( + summary, n[1]; + /* block */ 3, + /* preds */ &[n[0], n[3]], + /* descs */ &[n[2]], + /* backs */ &[] + ); + + assert_node!( + summary, n[2]; + /* block */ 5, + /* preds */ &[n[1]], + /* descs */ &[], + /* backs */ &[] + ); + + assert_node!( + summary, n[3]; + /* block */ 2, + /* preds */ &[n[0]], + /* descs */ &[], + /* backs */ &[] + ); +} + +#[test] +fn loops_in_branches_summary() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(8), + /* B2, L5 */ Nop, + /* B3, L6 */ LdFalse, + /* */ BrFalse(3), + /* B5, L7 */ LdTrue, + /* */ BrTrue(2), + /* B7, L8 */ Branch(13), + /* B8, L1 */ Nop, + /* B9, L2 */ LdTrue, + /* */ BrTrue(8), + /* B11, L3 */ LdFalse, + /* */ BrFalse(9), + /* B13, L4 */ Ret, + ])) + }; + + let n: Vec<_> = summary.preorder().collect(); + + assert_eq!(n.len(), 9); + + assert_node!( + summary, n[0]; + /* block */ 0, + /* preds */ &[], + /* descs */ &[n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]], + /* backs */ &[] + ); + + assert_node!( + summary, n[1]; + /* block */ 8, + /* preds */ &[n[0]], + /* descs */ &[n[2], n[3], n[4]], + /* backs */ &[n[2]] + ); + + assert_node!( + summary, n[2]; + /* block */ 9, + /* preds */ &[n[1]], + /* descs */ &[n[3], n[4]], + /* backs */ &[n[3]] + ); + + assert_node!( + summary, n[3]; + /* block */ 11, + /* preds */ &[n[2]], + /* descs */ &[n[4]], + /* backs */ &[] + ); + + assert_node!( + summary, n[4]; + /* block */ 13, + /* preds */ &[n[3], n[8]], + /* descs */ &[], + /* backs */ &[] + ); + + assert_node!( + summary, n[5]; + /* block */ 2, + /* preds */ &[n[0]], + /* descs */ &[n[6], n[7], n[8]], + /* backs */ &[n[7]] + ); + + assert_node!( + summary, n[6]; + /* block */ 3, + /* preds */ &[n[5]], + /* descs */ &[n[7], n[8]], + /* backs */ &[n[6]] + ); + + assert_node!( + summary, n[7]; + /* block */ 5, + /* preds */ &[n[6]], + /* descs */ &[n[8]], + /* backs */ &[] + ); + + assert_node!( + summary, n[8]; + /* block */ 7, + /* preds */ &[n[7]], + /* descs */ &[], + /* backs */ &[] + ); +} + +#[test] +fn loop_collapsing() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ LdTrue, + /* */ BrTrue(4), + /* B2, L2 */ Nop, + /* */ Branch(0), + /* B4, L1 */ Ret, + ])) + }; + + let mut partition = LoopPartition::new(&summary); + let n: Vec<_> = summary.preorder().collect(); + + for id in &n { + assert_eq!(*id, partition.containing_loop(*id), "Self-parent {:?}", id); + } + + assert_eq!(partition.collapse_loop(n[0], &[n[2]].into()), 1); + assert_eq!(partition.containing_loop(n[0]), n[0]); + assert_eq!(partition.containing_loop(n[1]), n[1]); + assert_eq!(partition.containing_loop(n[2]), n[0]); +} + +#[test] +fn nested_loop_collapsing() { + let summary = { + use Bytecode::*; + LoopSummary::new(&VMControlFlowGraph::new(&[ + /* B0, L0 */ Nop, + /* B1, L1 */ LdTrue, + /* */ BrTrue(1), + /* B3, L2 */ LdFalse, + /* */ BrFalse(0), + /* B5, L3 */ LdTrue, + /* */ BrTrue(0), + /* B7, L4 */ Ret, + ])) + }; + + let mut partition = LoopPartition::new(&summary); + let n: Vec<_> = summary.preorder().collect(); + + // Self-loop is a special case -- its depth should still be bumped. + assert_eq!(partition.collapse_loop(n[1], &[].into()), 1); + assert_eq!(partition.collapse_loop(n[0], &[n[1], n[2]].into()), 2); + assert_eq!(partition.collapse_loop(n[0], &[n[0], n[3]].into()), 3); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs new file mode 100644 index 000000000..7e8324021 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs @@ -0,0 +1,100 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::unit_tests::production_config; +use move_binary_format::file_format::{ + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, + IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + Visibility::Public, +}; +use move_bytecode_verifier::meter::BoundMeter; +use move_core_types::{identifier::Identifier, vm_status::StatusCode}; + +const MAX_BASIC_BLOCKS: u16 = 1024; +const MAX_LOCALS: u8 = 255; + +const NUM_FUNCTIONS: u16 = 16; + +#[test] +fn many_backedges() { + let mut m = empty_module(); + + // signature of locals in f1..f + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::U8) + .take(MAX_LOCALS as usize) + .collect(), + )); + + // create returns_bool_and_u64 + m.signatures + .push(Signature(vec![SignatureToken::Bool, SignatureToken::U8])); + m.identifiers + .push(Identifier::new("returns_bool_and_u64").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(0), + return_: SignatureIndex(2), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::LdTrue, Bytecode::LdU8(0), Bytecode::Ret], + }), + }); + + // create other functions + for i in 1..(NUM_FUNCTIONS + 1) { + m.identifiers + .push(Identifier::new(format!("f{}", i)).unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(i + 1), // the +1 accounts for returns_bool_and_u64 + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(i), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(1), + code: vec![], + }), + }); + + let code = &mut m.function_defs[i as usize].code.as_mut().unwrap().code; + + for _ in 0..(MAX_BASIC_BLOCKS - MAX_LOCALS as u16 - 2) { + code.push(Bytecode::LdTrue); + code.push(Bytecode::BrTrue(0)); + } + for i in 0..MAX_LOCALS { + code.push(Bytecode::Call(FunctionHandleIndex(0))); // calls returns_bool_and_u64 + code.push(Bytecode::StLoc(i as u8)); // i'th local is now available for the first time + code.push(Bytecode::BrTrue(0)); + } + code.push(Bytecode::Ret); + } + + let config = production_config(); + let mut meter = BoundMeter::new(&config); + let result = move_bytecode_verifier::verify_module_with_config_for_test( + "many_backedges", + &config, + &m, + &mut meter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CONSTRAINT_NOT_SATISFIED + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/mod.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/mod.rs new file mode 100644 index 000000000..a9b65e033 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/mod.rs @@ -0,0 +1,56 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_vm_config::verifier::{ + VerifierConfig, DEFAULT_MAX_CONSTANT_VECTOR_LEN, DEFAULT_MAX_IDENTIFIER_LENGTH, +}; + +pub mod ability_field_requirements_tests; +pub mod binary_samples; +pub mod bounds_tests; +pub mod code_unit_tests; +pub mod constants_tests; +pub mod control_flow_tests; +pub mod dependencies_tests; +pub mod duplication_tests; +pub mod generic_ops_tests; +pub mod large_type_test; +pub mod limit_tests; +pub mod locals; +pub mod loop_summary_tests; +pub mod many_back_edges; +pub mod multi_pass_tests; +pub mod negative_stack_size_tests; +pub mod reference_safety_tests; +pub mod signature_tests; +pub mod struct_defs_tests; +pub mod vec_pack_tests; + +/// Configuration used in production. +pub(crate) fn production_config() -> VerifierConfig { + VerifierConfig { + max_loop_depth: Some(5), + max_generic_instantiation_length: Some(32), + max_function_parameters: Some(128), + max_basic_blocks: Some(1024), + max_basic_blocks_in_script: Some(1024), + max_value_stack_size: 1024, + max_type_nodes: Some(256), + max_push_size: Some(10000), + max_dependency_depth: Some(100), + max_struct_definitions: Some(200), + max_fields_in_struct: Some(30), + max_function_definitions: Some(1000), + + // Do not use back edge constraints as they are superseded by metering + max_back_edges_per_function: None, + max_back_edges_per_module: None, + + // Same as the default. + max_per_fun_meter_units: Some(1000 * 8000), + max_per_mod_meter_units: Some(1000 * 8000), + max_constant_vector_len: Some(DEFAULT_MAX_CONSTANT_VECTOR_LEN), + max_idenfitier_len: Some(DEFAULT_MAX_IDENTIFIER_LENGTH), + } +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/multi_pass_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/multi_pass_tests.rs new file mode 100644 index 000000000..d244f6dd3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/multi_pass_tests.rs @@ -0,0 +1,23 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::CompiledModule; +use move_bytecode_verifier::{ + ability_field_requirements, constants, instantiation_loops::InstantiationLoopChecker, + DuplicationChecker, InstructionConsistency, RecursiveStructDefChecker, SignatureChecker, +}; +use proptest::prelude::*; + +proptest! { + #[test] + fn check_verifier_passes(module in CompiledModule::valid_strategy(20)) { + DuplicationChecker::verify_module(&module).expect("DuplicationChecker failure"); + SignatureChecker::verify_module(&module).expect("SignatureChecker failure"); + InstructionConsistency::verify_module(&module).expect("InstructionConsistency failure"); + constants::verify_module(&module).expect("constants failure"); + ability_field_requirements::verify_module(&module).expect("ability_field_requirements failure"); + RecursiveStructDefChecker::verify_module(&module).expect("RecursiveStructDefChecker failure"); + InstantiationLoopChecker::verify_module(&module).expect("InstantiationLoopChecker failure"); + } +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/negative_stack_size_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/negative_stack_size_tests.rs new file mode 100644 index 000000000..3b1c387e4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/negative_stack_size_tests.rs @@ -0,0 +1,51 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::support::dummy_procedure_module; +use move_binary_format::file_format::Bytecode; +use move_bytecode_verifier::meter::DummyMeter; +use move_bytecode_verifier::CodeUnitVerifier; +use move_core_types::vm_status::StatusCode; + +#[test] +fn one_pop_no_push() { + let module = dummy_procedure_module(vec![Bytecode::Pop, Bytecode::Ret]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK + ); +} + +#[test] +fn one_pop_one_push() { + // Height: 0 + (-1 + 1) = 0 would have passed original usage verifier + let module = dummy_procedure_module(vec![Bytecode::ReadRef, Bytecode::Ret]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK + ); +} + +#[test] +fn two_pop_one_push() { + // Height: 0 + 1 + (-2 + 1) = 0 would have passed original usage verifier + let module = dummy_procedure_module(vec![Bytecode::LdU64(0), Bytecode::Add, Bytecode::Ret]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK + ); +} + +#[test] +fn two_pop_no_push() { + let module = dummy_procedure_module(vec![Bytecode::WriteRef, Bytecode::Ret]); + let result = CodeUnitVerifier::verify_module(&Default::default(), &module, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs new file mode 100644 index 000000000..35ae4385f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs @@ -0,0 +1,435 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::unit_tests::production_config; +use move_binary_format::file_format::{ + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, + IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + Visibility::Public, +}; +use move_bytecode_verifier::meter::BoundMeter; +use move_core_types::{identifier::Identifier, vm_status::StatusCode}; + +#[test] +fn test_bicliques() { + // See also: github.com/aptos-labs/aptos-core/security/advisories/GHSA-xm6p-ffcq-5p2v + const NUM_LOCALS: u8 = 128; + const NUM_CALLS: u16 = 76; + const NUM_FUNCTIONS: u16 = 1; + + let mut m = empty_module(); + + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + }), + }); + + // create take_and_return_references + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U64))) + .take(NUM_LOCALS as usize) + .collect(), + )); + m.identifiers + .push(Identifier::new("take_and_return_references").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(1), + return_: SignatureIndex(1), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(1), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![], + }), + }); + let code = &mut m.function_defs[1].code.as_mut().unwrap().code; + for i in 0..NUM_LOCALS { + code.push(Bytecode::MoveLoc(i)); + } + code.push(Bytecode::Ret); + + // create swallow_references + m.identifiers + .push(Identifier::new("swallow_references").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(2), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Ret], + }), + }); + + // create other functions + for i in 1..(NUM_FUNCTIONS + 1) { + m.identifiers + .push(Identifier::new(format!("f{}", i)).unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(i + 2), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(i + 2), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![], + }), + }); + let code = &mut m.function_defs[i as usize + 2].code.as_mut().unwrap().code; + for j in 0..NUM_LOCALS { + code.push(Bytecode::CopyLoc(j)); + } + for _ in 0..NUM_CALLS { + code.push(Bytecode::Call(FunctionHandleIndex(1))); + } + code.push(Bytecode::Call(FunctionHandleIndex(2))); + code.push(Bytecode::Ret); + } + + let config = production_config(); + let mut meter = BoundMeter::new(&config); + let result = move_bytecode_verifier::verify_module_with_config_for_test( + "test_bicliques", + &config, + &m, + &mut meter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CONSTRAINT_NOT_SATISFIED + ); +} + +#[test] +fn test_merge_state_large_graph() { + // See also: github.com/aptos-labs/aptos-core/security/advisories/GHSA-g8v8-fw4c-8h82 + const N: u8 = 127; + const NUM_NOP_BLOCKS: u16 = 950; + const NUM_FUNCTIONS: u16 = 18; + + let mut m = empty_module(); + + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + }), + }); + + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U8))) + .take(N as usize) + .collect(), + )); + + m.identifiers.push(Identifier::new("return_refs").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + parameters: SignatureIndex(0), + return_: SignatureIndex(1), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(1), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + }), + }); + + m.identifiers + .push(Identifier::new("take_and_return_refs").unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + parameters: SignatureIndex(1), + return_: SignatureIndex(1), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(2), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], + }), + }); + + for i in 0..NUM_FUNCTIONS { + m.identifiers + .push(Identifier::new(format!("f{}", i)).unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(i + 3), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(i + 3), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(1), + code: vec![], + }), + }); + let code = &mut m.function_defs[i as usize + 3].code.as_mut().unwrap().code; + for j in 0..N { + code.push(Bytecode::CopyLoc(j)); + } + code.push(Bytecode::Call(FunctionHandleIndex(2))); + for j in 0..N { + code.push(Bytecode::StLoc(N + j)); + } + for _ in 0..NUM_NOP_BLOCKS { + code.push(Bytecode::LdTrue); + code.push(Bytecode::BrTrue(0)); + } + + code.push(Bytecode::Ret); + } + + let config = production_config(); + let mut meter = BoundMeter::new(&config); + let result = move_bytecode_verifier::verify_module_with_config_for_test( + "test_merge_state_large_graph", + &config, + &m, + &mut meter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CONSTRAINT_NOT_SATISFIED + ); +} + +#[test] +fn test_merge_state() { + // See also: github.com/aptos-labs/aptos-core/security/advisories/GHSA-g8v8-fw4c-8h82 + const NUM_NOP_BLOCKS: u16 = 965; + const NUM_LOCALS: u8 = 32; + const NUM_FUNCTIONS: u16 = 21; + + let mut m = empty_module(); + + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], + }), + }); + + m.signatures + .push(Signature(vec![SignatureToken::Reference(Box::new( + SignatureToken::U8, + ))])); + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U8))) + .take(NUM_LOCALS as usize - 1) + .collect(), + )); + + for i in 0..NUM_FUNCTIONS { + m.identifiers + .push(Identifier::new(format!("f{}", i)).unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(i + 1), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(i + 1), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(2), + code: vec![], + }), + }); + let code = &mut m.function_defs[i as usize + 1].code.as_mut().unwrap().code; + // create reference id + code.push(Bytecode::CopyLoc(0)); + code.push(Bytecode::StLoc(1)); + // create a path of length NUM_LOCALS - 1 in the borrow graph + for j in 0..(NUM_LOCALS - 2) { + // create Ref(new_id) and factor in empty-path edge id -> new_id + code.push(Bytecode::CopyLoc(1)); + // can't leave those references on stack since basic blocks need to be stack-neutral + code.push(Bytecode::StLoc(j + 2)); + } + for _ in 0..NUM_NOP_BLOCKS { + code.push(Bytecode::LdTrue); + // create back edge to first block + code.push(Bytecode::BrTrue(0)); + } + + code.push(Bytecode::Ret); + } + + let config = production_config(); + let mut meter = BoundMeter::new(&config); + let result = move_bytecode_verifier::verify_module_with_config_for_test( + "test_merge_state", + &config, + &m, + &mut meter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CONSTRAINT_NOT_SATISFIED + ); +} + +#[test] +fn test_copyloc_pop() { + // See also: github.com/aptos-labs/aptos-core/security/advisories/GHSA-2qvr-c9qp-wch7 + const NUM_COPYLOCS: u16 = 1880; + const NUM_CHILDREN: u16 = 1020; + const NUM_FUNCTIONS: u16 = 2; + + let mut m = empty_module(); + + // parameters of f0, f1, ... + m.signatures + .push(Signature(vec![SignatureToken::Reference(Box::new( + SignatureToken::Vector(Box::new(SignatureToken::U8)), + ))])); + // locals of f0, f1, ... + m.signatures.push(Signature(vec![ + SignatureToken::Reference(Box::new(SignatureToken::Vector(Box::new( + SignatureToken::U8, + )))), + SignatureToken::U8, // ignore this, it's just here because I don't want to fix indices and the TypeParameter after removing the collision + ])); + // for VecImmBorrow + m.signatures.push(Signature( + std::iter::repeat(SignatureToken::U8).take(1).collect(), + )); + m.signatures + .push(Signature(vec![SignatureToken::TypeParameter(0)])); + + for i in 0..NUM_FUNCTIONS { + m.identifiers + .push(Identifier::new(format!("f{}", i)).unwrap()); + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(i), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(i), + visibility: Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(2), + code: vec![], + }), + }); + let code = &mut m.function_defs[i as usize].code.as_mut().unwrap().code; + + // create reference id + code.push(Bytecode::CopyLoc(0)); + code.push(Bytecode::StLoc(1)); + // create NUM_CHLIDREN children of id + for _ in 0..NUM_CHILDREN { + code.push(Bytecode::CopyLoc(1)); + code.push(Bytecode::LdU64(0)); + code.push(Bytecode::VecImmBorrow(SignatureIndex(3))); + } + // then do a whole lot of copylocs on that reference + for _ in 0..NUM_COPYLOCS { + code.push(Bytecode::CopyLoc(1)); + code.push(Bytecode::Pop); + } + for _ in 0..NUM_CHILDREN { + code.push(Bytecode::Pop); + } + + code.push(Bytecode::Ret); + } + + let config = production_config(); + let mut meter = BoundMeter::new(&config); + let result = move_bytecode_verifier::verify_module_with_config_for_test( + "test_copyloc_pop", + &config, + &m, + &mut meter, + ); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CONSTRAINT_NOT_SATISFIED + ); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs new file mode 100644 index 000000000..3f9989200 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs @@ -0,0 +1,227 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::unit_tests::production_config; +use invalid_mutations::signature::{FieldRefMutation, SignatureRefMutation}; +use move_binary_format::file_format::{ + Bytecode::*, CompiledModule, SignatureToken::*, Visibility::Public, *, +}; +use move_bytecode_verifier::{ + meter::DummyMeter, verify_module_unmetered, verify_module_with_config_for_test, + SignatureChecker, +}; +use move_core_types::{ + account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, +}; +use proptest::{collection::vec, prelude::*, sample::Index as PropIndex}; + +#[test] +fn test_reference_of_reference() { + let mut m = basic_test_module(); + m.signatures[0] = Signature(vec![Reference(Box::new(Reference(Box::new( + SignatureToken::Bool, + ))))]); + let errors = SignatureChecker::verify_module(&m); + assert!(errors.is_err()); +} + +proptest! { + #[test] + fn valid_signatures(module in CompiledModule::valid_strategy(20)) { + prop_assert!(SignatureChecker::verify_module(&module).is_ok()) + } + + #[test] + fn double_refs( + mut module in CompiledModule::valid_strategy(20), + mutations in vec((any::(), any::()), 0..20), + ) { + let context = SignatureRefMutation::new(&mut module, mutations); + let expected_violations = context.apply(); + + let result = SignatureChecker::verify_module(&module); + + prop_assert_eq!(expected_violations, result.is_err()); + } + + #[test] + fn field_def_references( + mut module in CompiledModule::valid_strategy(20), + mutations in vec((any::(), any::()), 0..40), + ) { + let context = FieldRefMutation::new(&mut module, mutations); + let expected_violations = context.apply(); + + let result = SignatureChecker::verify_module(&module); + + prop_assert_eq!(expected_violations, result.is_err()); + } +} + +#[test] +fn no_verify_locals_good() { + let compiled_module_good = CompiledModule { + version: move_binary_format::file_format_common::VERSION_MAX, + module_handles: vec![ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }], + self_module_handle_idx: ModuleHandleIndex(0), + struct_handles: vec![], + signatures: vec![ + Signature(vec![Address]), + Signature(vec![U64]), + Signature(vec![]), + ], + function_handles: vec![ + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + return_: SignatureIndex(2), + parameters: SignatureIndex(0), + type_parameters: vec![], + }, + FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(2), + return_: SignatureIndex(2), + parameters: SignatureIndex(1), + type_parameters: vec![], + }, + ], + field_handles: vec![], + friend_decls: vec![], + struct_def_instantiations: vec![], + function_instantiations: vec![], + field_instantiations: vec![], + identifiers: vec![ + Identifier::new("Bad").unwrap(), + Identifier::new("blah").unwrap(), + Identifier::new("foo").unwrap(), + ], + address_identifiers: vec![AccountAddress::new([0; AccountAddress::LENGTH])], + constant_pool: vec![], + metadata: vec![], + struct_defs: vec![], + function_defs: vec![ + FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Visibility::Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![Ret], + }), + }, + FunctionDefinition { + function: FunctionHandleIndex(1), + visibility: Visibility::Public, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(1), + code: vec![Ret], + }), + }, + ], + }; + assert!(verify_module_unmetered(&compiled_module_good).is_ok()); +} + +#[test] +fn big_signature_test() { + const N_TYPE_PARAMS: usize = 5; + const INSTANTIATION_DEPTH: usize = 3; + const VECTOR_DEPTH: usize = 250; + let mut st = SignatureToken::U8; + for _ in 0..VECTOR_DEPTH { + st = SignatureToken::Vector(Box::new(st)); + } + for _ in 0..INSTANTIATION_DEPTH { + let type_params = vec![st; N_TYPE_PARAMS]; + st = SignatureToken::StructInstantiation(StructHandleIndex(0), type_params); + } + + const N_READPOP: u16 = 7500; + + let mut code = vec![]; + // 1. ImmBorrowLoc: ... ref + // 2. ReadRef: ... value + // 3. Pop: ... + for _ in 0..N_READPOP { + code.push(Bytecode::ImmBorrowLoc(0)); + code.push(Bytecode::ReadRef); + code.push(Bytecode::Pop); + } + code.push(Bytecode::Ret); + + let type_param_constraints = StructTypeParameter { + constraints: AbilitySet::EMPTY, + is_phantom: false, + }; + + let module = CompiledModule { + version: 5, + self_module_handle_idx: ModuleHandleIndex(0), + module_handles: vec![ModuleHandle { + address: AddressIdentifierIndex(0), + name: IdentifierIndex(0), + }], + struct_handles: vec![StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(1), + abilities: AbilitySet::ALL, + type_parameters: vec![type_param_constraints; N_TYPE_PARAMS], + }], + function_handles: vec![FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(1), + return_: SignatureIndex(0), + type_parameters: vec![], + }], + field_handles: vec![], + friend_decls: vec![], + struct_def_instantiations: vec![], + function_instantiations: vec![], + field_instantiations: vec![], + signatures: vec![Signature(vec![]), Signature(vec![st])], + identifiers: vec![ + Identifier::new("f").unwrap(), + Identifier::new("generic_struct").unwrap(), + ], + address_identifiers: vec![AccountAddress::ONE], + constant_pool: vec![], + metadata: vec![], + struct_defs: vec![StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Native, + }], + function_defs: vec![FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Public, + is_entry: true, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code, + }), + }], + }; + + // save module and verify that it can ser/de + let mut mvbytes = vec![]; + module.serialize(&mut mvbytes).unwrap(); + let module = CompiledModule::deserialize_with_defaults(&mvbytes).unwrap(); + + let res = verify_module_with_config_for_test( + "big_signature_test", + &production_config(), + &module, + &mut DummyMeter, + ) + .unwrap_err(); + assert_eq!(res.major_status(), StatusCode::TOO_MANY_TYPE_NODES); +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/struct_defs_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/struct_defs_tests.rs new file mode 100644 index 000000000..71fdc4660 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/struct_defs_tests.rs @@ -0,0 +1,14 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::file_format::CompiledModule; +use move_bytecode_verifier::RecursiveStructDefChecker; +use proptest::prelude::*; + +proptest! { + #[test] + fn valid_recursive_struct_defs(module in CompiledModule::valid_strategy(20)) { + prop_assert!(RecursiveStructDefChecker::verify_module(&module).is_ok()); + } +} diff --git a/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs new file mode 100644 index 000000000..672c255c7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs @@ -0,0 +1,71 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::unit_tests::production_config; +use move_binary_format::file_format::{ + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, + IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, Visibility, +}; +use move_bytecode_verifier::meter::DummyMeter; +use move_core_types::{identifier::Identifier, vm_status::StatusCode}; + +fn vec_sig(len: usize) -> SignatureToken { + if len > 0 { + SignatureToken::Vector(Box::new(vec_sig(len - 1))) + } else { + SignatureToken::U8 + } +} + +#[test] +fn test_vec_pack() { + let mut m = empty_module(); + + let sig = SignatureIndex(m.signatures.len() as u16); + m.signatures.push(Signature(vec![vec_sig(255)])); + + m.function_defs.push(FunctionDefinition { + function: FunctionHandleIndex(0), + visibility: Visibility::Private, + is_entry: false, + acquires_global_resources: vec![], + code: Some(CodeUnit { + locals: SignatureIndex(0), + code: vec![], + }), + }); + + m.function_handles.push(FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(m.identifiers.len() as u16), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }); + m.identifiers + .push(Identifier::new("foo".to_string()).unwrap()); + + const COUNT: usize = 3000; + + m.function_defs[0].code.as_mut().unwrap().code = + std::iter::once(&[Bytecode::VecPack(sig, 0)][..]) + .chain( + std::iter::repeat( + &[Bytecode::VecUnpack(sig, 1024), Bytecode::VecPack(sig, 1024)][..], + ) + .take(COUNT), + ) + .chain(std::iter::once(&[Bytecode::Pop, Bytecode::Ret][..])) + .flatten() + .cloned() + .collect(); + + let res = move_bytecode_verifier::verify_module_with_config_for_test( + "test_vec_pack", + &production_config(), + &m, + &mut DummyMeter, + ) + .unwrap_err(); + assert_eq!(res.major_status(), StatusCode::VALUE_STACK_PUSH_OVERFLOW); +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/Cargo.toml b/vendors/move/crates/bytecode-verifier-transactional-tests/Cargo.toml new file mode 100644 index 000000000..f1b90ffc4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "bytecode-verifier-transactional-tests" +version = "0.1.0" +authors = ["Diem Association "] +publish = false +edition = "2021" +license = "Apache-2.0" + +[dev-dependencies] +datatest-stable.workspace = true +move-transactional-test-runner.workspace = true + +[[test]] +name = "tests" +harness = false + +[dependencies] diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/src/lib.rs b/vendors/move/crates/bytecode-verifier-transactional-tests/src/lib.rs new file mode 100644 index 000000000..0cd3c22c1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/src/lib.rs @@ -0,0 +1,7 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +// Empty src/lib.rs to get rusty-tags working. diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/procedure_args.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/procedure_args.exp new file mode 100644 index 000000000..af6b9936e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/procedure_args.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 9-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CALL_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/procedure_args.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/procedure_args.mvir new file mode 100644 index 000000000..a65a7e7f1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/procedure_args.mvir @@ -0,0 +1,19 @@ +//# publish +module 0x42.Test { + public t(fr: u64) { + label b0: + return; + } +} + +//# run +module 0x42.m { +import 0x42.Test; + +entry foo() { +label b0: + // args type mismatch + Test.t(true); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_has_resource_field.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_has_resource_field.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_has_resource_field.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_has_resource_field.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_has_resource_field.mvir new file mode 100644 index 000000000..d115c6fbb --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/resource_has_resource_field.mvir @@ -0,0 +1,5 @@ +//# publish +module 0x42.Test { + struct All has key, store, copy, drop { b: bool } + struct T { f: Self.All } // can drop abilities +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.exp new file mode 100644 index 000000000..8fc6a9cda --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x42::Test, + indices: [(StructDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.mvir new file mode 100644 index 000000000..b4ac76320 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/ability_field_requirements/unrestricted_has_resource_field.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x42.Test { +import 0x1.XUS; + struct Coin has store { value: u64 } + struct T has copy, drop { + // does not have copy or drop + fc: Self.Coin, + fint: u64, + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/128_params_and_128_locals.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/128_params_and_128_locals.exp new file mode 100644 index 000000000..0d1108cb0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/128_params_and_128_locals.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-265: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: TOO_MANY_LOCALS, + sub_status: None, + location: undefined, + indices: [(FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/128_params_and_128_locals.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/128_params_and_128_locals.mvir new file mode 100644 index 000000000..409900827 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/128_params_and_128_locals.mvir @@ -0,0 +1,265 @@ +//# publish +module 0x1.M { + foo( + p1 : u8, + p2 : u8, + p3 : u8, + p4 : u8, + p5 : u8, + p6 : u8, + p7 : u8, + p8 : u8, + p9 : u8, + p10 : u8, + p11 : u8, + p12 : u8, + p13 : u8, + p14 : u8, + p15 : u8, + p16 : u8, + p17 : u8, + p18 : u8, + p19 : u8, + p20 : u8, + p21 : u8, + p22 : u8, + p23 : u8, + p24 : u8, + p25 : u8, + p26 : u8, + p27 : u8, + p28 : u8, + p29 : u8, + p30 : u8, + p31 : u8, + p32 : u8, + p33 : u8, + p34 : u8, + p35 : u8, + p36 : u8, + p37 : u8, + p38 : u8, + p39 : u8, + p40 : u8, + p41 : u8, + p42 : u8, + p43 : u8, + p44 : u8, + p45 : u8, + p46 : u8, + p47 : u8, + p48 : u8, + p49 : u8, + p50 : u8, + p51 : u8, + p52 : u8, + p53 : u8, + p54 : u8, + p55 : u8, + p56 : u8, + p57 : u8, + p58 : u8, + p59 : u8, + p60 : u8, + p61 : u8, + p62 : u8, + p63 : u8, + p64 : u8, + p65 : u8, + p66 : u8, + p67 : u8, + p68 : u8, + p69 : u8, + p70 : u8, + p71 : u8, + p72 : u8, + p73 : u8, + p74 : u8, + p75 : u8, + p76 : u8, + p77 : u8, + p78 : u8, + p79 : u8, + p80 : u8, + p81 : u8, + p82 : u8, + p83 : u8, + p84 : u8, + p85 : u8, + p86 : u8, + p87 : u8, + p88 : u8, + p89 : u8, + p90 : u8, + p91 : u8, + p92 : u8, + p93 : u8, + p94 : u8, + p95 : u8, + p96 : u8, + p97 : u8, + p98 : u8, + p99 : u8, + p100 : u8, + p101 : u8, + p102 : u8, + p103 : u8, + p104 : u8, + p105 : u8, + p106 : u8, + p107 : u8, + p108 : u8, + p109 : u8, + p110 : u8, + p111 : u8, + p112 : u8, + p113 : u8, + p114 : u8, + p115 : u8, + p116 : u8, + p117 : u8, + p118 : u8, + p119 : u8, + p120 : u8, + p121 : u8, + p122 : u8, + p123 : u8, + p124 : u8, + p125 : u8, + p126 : u8, + p127 : u8, + p128 : u8, + ) { + let x1 : u8; + let x2 : u8; + let x3 : u8; + let x4 : u8; + let x5 : u8; + let x6 : u8; + let x7 : u8; + let x8 : u8; + let x9 : u8; + let x10 : u8; + let x11 : u8; + let x12 : u8; + let x13 : u8; + let x14 : u8; + let x15 : u8; + let x16 : u8; + let x17 : u8; + let x18 : u8; + let x19 : u8; + let x20 : u8; + let x21 : u8; + let x22 : u8; + let x23 : u8; + let x24 : u8; + let x25 : u8; + let x26 : u8; + let x27 : u8; + let x28 : u8; + let x29 : u8; + let x30 : u8; + let x31 : u8; + let x32 : u8; + let x33 : u8; + let x34 : u8; + let x35 : u8; + let x36 : u8; + let x37 : u8; + let x38 : u8; + let x39 : u8; + let x40 : u8; + let x41 : u8; + let x42 : u8; + let x43 : u8; + let x44 : u8; + let x45 : u8; + let x46 : u8; + let x47 : u8; + let x48 : u8; + let x49 : u8; + let x50 : u8; + let x51 : u8; + let x52 : u8; + let x53 : u8; + let x54 : u8; + let x55 : u8; + let x56 : u8; + let x57 : u8; + let x58 : u8; + let x59 : u8; + let x60 : u8; + let x61 : u8; + let x62 : u8; + let x63 : u8; + let x64 : u8; + let x65 : u8; + let x66 : u8; + let x67 : u8; + let x68 : u8; + let x69 : u8; + let x70 : u8; + let x71 : u8; + let x72 : u8; + let x73 : u8; + let x74 : u8; + let x75 : u8; + let x76 : u8; + let x77 : u8; + let x78 : u8; + let x79 : u8; + let x80 : u8; + let x81 : u8; + let x82 : u8; + let x83 : u8; + let x84 : u8; + let x85 : u8; + let x86 : u8; + let x87 : u8; + let x88 : u8; + let x89 : u8; + let x90 : u8; + let x91 : u8; + let x92 : u8; + let x93 : u8; + let x94 : u8; + let x95 : u8; + let x96 : u8; + let x97 : u8; + let x98 : u8; + let x99 : u8; + let x100 : u8; + let x101 : u8; + let x102 : u8; + let x103 : u8; + let x104 : u8; + let x105 : u8; + let x106 : u8; + let x107 : u8; + let x108 : u8; + let x109 : u8; + let x110 : u8; + let x111 : u8; + let x112 : u8; + let x113 : u8; + let x114 : u8; + let x115 : u8; + let x116 : u8; + let x117 : u8; + let x118 : u8; + let x119 : u8; + let x120 : u8; + let x121 : u8; + let x122 : u8; + let x123 : u8; + let x124 : u8; + let x125 : u8; + let x126 : u8; + let x127 : u8; + let x128 : u8; + label b0: + return; + } +} +// check: TOO_MANY_LOCALS diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.exp new file mode 100644 index 000000000..f5cf0a779 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-264: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: TOO_MANY_LOCALS, + sub_status: None, + location: undefined, + indices: [(FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.mvir new file mode 100644 index 000000000..654674e5b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/1_param_and_255_locals.mvir @@ -0,0 +1,264 @@ +//# publish +module 0x1.M { + foo(p1: u8) { + let x1 : u8; + let x2 : u8; + let x3 : u8; + let x4 : u8; + let x5 : u8; + let x6 : u8; + let x7 : u8; + let x8 : u8; + let x9 : u8; + let x10 : u8; + let x11 : u8; + let x12 : u8; + let x13 : u8; + let x14 : u8; + let x15 : u8; + let x16 : u8; + let x17 : u8; + let x18 : u8; + let x19 : u8; + let x20 : u8; + let x21 : u8; + let x22 : u8; + let x23 : u8; + let x24 : u8; + let x25 : u8; + let x26 : u8; + let x27 : u8; + let x28 : u8; + let x29 : u8; + let x30 : u8; + let x31 : u8; + let x32 : u8; + let x33 : u8; + let x34 : u8; + let x35 : u8; + let x36 : u8; + let x37 : u8; + let x38 : u8; + let x39 : u8; + let x40 : u8; + let x41 : u8; + let x42 : u8; + let x43 : u8; + let x44 : u8; + let x45 : u8; + let x46 : u8; + let x47 : u8; + let x48 : u8; + let x49 : u8; + let x50 : u8; + let x51 : u8; + let x52 : u8; + let x53 : u8; + let x54 : u8; + let x55 : u8; + let x56 : u8; + let x57 : u8; + let x58 : u8; + let x59 : u8; + let x60 : u8; + let x61 : u8; + let x62 : u8; + let x63 : u8; + let x64 : u8; + let x65 : u8; + let x66 : u8; + let x67 : u8; + let x68 : u8; + let x69 : u8; + let x70 : u8; + let x71 : u8; + let x72 : u8; + let x73 : u8; + let x74 : u8; + let x75 : u8; + let x76 : u8; + let x77 : u8; + let x78 : u8; + let x79 : u8; + let x80 : u8; + let x81 : u8; + let x82 : u8; + let x83 : u8; + let x84 : u8; + let x85 : u8; + let x86 : u8; + let x87 : u8; + let x88 : u8; + let x89 : u8; + let x90 : u8; + let x91 : u8; + let x92 : u8; + let x93 : u8; + let x94 : u8; + let x95 : u8; + let x96 : u8; + let x97 : u8; + let x98 : u8; + let x99 : u8; + let x100 : u8; + let x101 : u8; + let x102 : u8; + let x103 : u8; + let x104 : u8; + let x105 : u8; + let x106 : u8; + let x107 : u8; + let x108 : u8; + let x109 : u8; + let x110 : u8; + let x111 : u8; + let x112 : u8; + let x113 : u8; + let x114 : u8; + let x115 : u8; + let x116 : u8; + let x117 : u8; + let x118 : u8; + let x119 : u8; + let x120 : u8; + let x121 : u8; + let x122 : u8; + let x123 : u8; + let x124 : u8; + let x125 : u8; + let x126 : u8; + let x127 : u8; + let x128 : u8; + let x129 : u8; + let x130 : u8; + let x131 : u8; + let x132 : u8; + let x133 : u8; + let x134 : u8; + let x135 : u8; + let x136 : u8; + let x137 : u8; + let x138 : u8; + let x139 : u8; + let x140 : u8; + let x141 : u8; + let x142 : u8; + let x143 : u8; + let x144 : u8; + let x145 : u8; + let x146 : u8; + let x147 : u8; + let x148 : u8; + let x149 : u8; + let x150 : u8; + let x151 : u8; + let x152 : u8; + let x153 : u8; + let x154 : u8; + let x155 : u8; + let x156 : u8; + let x157 : u8; + let x158 : u8; + let x159 : u8; + let x160 : u8; + let x161 : u8; + let x162 : u8; + let x163 : u8; + let x164 : u8; + let x165 : u8; + let x166 : u8; + let x167 : u8; + let x168 : u8; + let x169 : u8; + let x170 : u8; + let x171 : u8; + let x172 : u8; + let x173 : u8; + let x174 : u8; + let x175 : u8; + let x176 : u8; + let x177 : u8; + let x178 : u8; + let x179 : u8; + let x180 : u8; + let x181 : u8; + let x182 : u8; + let x183 : u8; + let x184 : u8; + let x185 : u8; + let x186 : u8; + let x187 : u8; + let x188 : u8; + let x189 : u8; + let x190 : u8; + let x191 : u8; + let x192 : u8; + let x193 : u8; + let x194 : u8; + let x195 : u8; + let x196 : u8; + let x197 : u8; + let x198 : u8; + let x199 : u8; + let x200 : u8; + let x201 : u8; + let x202 : u8; + let x203 : u8; + let x204 : u8; + let x205 : u8; + let x206 : u8; + let x207 : u8; + let x208 : u8; + let x209 : u8; + let x210 : u8; + let x211 : u8; + let x212 : u8; + let x213 : u8; + let x214 : u8; + let x215 : u8; + let x216 : u8; + let x217 : u8; + let x218 : u8; + let x219 : u8; + let x220 : u8; + let x221 : u8; + let x222 : u8; + let x223 : u8; + let x224 : u8; + let x225 : u8; + let x226 : u8; + let x227 : u8; + let x228 : u8; + let x229 : u8; + let x230 : u8; + let x231 : u8; + let x232 : u8; + let x233 : u8; + let x234 : u8; + let x235 : u8; + let x236 : u8; + let x237 : u8; + let x238 : u8; + let x239 : u8; + let x240 : u8; + let x241 : u8; + let x242 : u8; + let x243 : u8; + let x244 : u8; + let x245 : u8; + let x246 : u8; + let x247 : u8; + let x248 : u8; + let x249 : u8; + let x250 : u8; + let x251 : u8; + let x252 : u8; + let x253 : u8; + let x254 : u8; + let x255 : u8; + label b0: + return; + } +} + +// check: TOO_MANY_LOCALS diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.exp new file mode 100644 index 000000000..cb05a36a1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 1-263: +Error: value (256) cannot exceed (255) diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.mvir new file mode 100644 index 000000000..19a5030b3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_locals.mvir @@ -0,0 +1,263 @@ +//# publish +module 0x1.M { + foo() { + let x1 : u8; + let x2 : u8; + let x3 : u8; + let x4 : u8; + let x5 : u8; + let x6 : u8; + let x7 : u8; + let x8 : u8; + let x9 : u8; + let x10 : u8; + let x11 : u8; + let x12 : u8; + let x13 : u8; + let x14 : u8; + let x15 : u8; + let x16 : u8; + let x17 : u8; + let x18 : u8; + let x19 : u8; + let x20 : u8; + let x21 : u8; + let x22 : u8; + let x23 : u8; + let x24 : u8; + let x25 : u8; + let x26 : u8; + let x27 : u8; + let x28 : u8; + let x29 : u8; + let x30 : u8; + let x31 : u8; + let x32 : u8; + let x33 : u8; + let x34 : u8; + let x35 : u8; + let x36 : u8; + let x37 : u8; + let x38 : u8; + let x39 : u8; + let x40 : u8; + let x41 : u8; + let x42 : u8; + let x43 : u8; + let x44 : u8; + let x45 : u8; + let x46 : u8; + let x47 : u8; + let x48 : u8; + let x49 : u8; + let x50 : u8; + let x51 : u8; + let x52 : u8; + let x53 : u8; + let x54 : u8; + let x55 : u8; + let x56 : u8; + let x57 : u8; + let x58 : u8; + let x59 : u8; + let x60 : u8; + let x61 : u8; + let x62 : u8; + let x63 : u8; + let x64 : u8; + let x65 : u8; + let x66 : u8; + let x67 : u8; + let x68 : u8; + let x69 : u8; + let x70 : u8; + let x71 : u8; + let x72 : u8; + let x73 : u8; + let x74 : u8; + let x75 : u8; + let x76 : u8; + let x77 : u8; + let x78 : u8; + let x79 : u8; + let x80 : u8; + let x81 : u8; + let x82 : u8; + let x83 : u8; + let x84 : u8; + let x85 : u8; + let x86 : u8; + let x87 : u8; + let x88 : u8; + let x89 : u8; + let x90 : u8; + let x91 : u8; + let x92 : u8; + let x93 : u8; + let x94 : u8; + let x95 : u8; + let x96 : u8; + let x97 : u8; + let x98 : u8; + let x99 : u8; + let x100 : u8; + let x101 : u8; + let x102 : u8; + let x103 : u8; + let x104 : u8; + let x105 : u8; + let x106 : u8; + let x107 : u8; + let x108 : u8; + let x109 : u8; + let x110 : u8; + let x111 : u8; + let x112 : u8; + let x113 : u8; + let x114 : u8; + let x115 : u8; + let x116 : u8; + let x117 : u8; + let x118 : u8; + let x119 : u8; + let x120 : u8; + let x121 : u8; + let x122 : u8; + let x123 : u8; + let x124 : u8; + let x125 : u8; + let x126 : u8; + let x127 : u8; + let x128 : u8; + let x129 : u8; + let x130 : u8; + let x131 : u8; + let x132 : u8; + let x133 : u8; + let x134 : u8; + let x135 : u8; + let x136 : u8; + let x137 : u8; + let x138 : u8; + let x139 : u8; + let x140 : u8; + let x141 : u8; + let x142 : u8; + let x143 : u8; + let x144 : u8; + let x145 : u8; + let x146 : u8; + let x147 : u8; + let x148 : u8; + let x149 : u8; + let x150 : u8; + let x151 : u8; + let x152 : u8; + let x153 : u8; + let x154 : u8; + let x155 : u8; + let x156 : u8; + let x157 : u8; + let x158 : u8; + let x159 : u8; + let x160 : u8; + let x161 : u8; + let x162 : u8; + let x163 : u8; + let x164 : u8; + let x165 : u8; + let x166 : u8; + let x167 : u8; + let x168 : u8; + let x169 : u8; + let x170 : u8; + let x171 : u8; + let x172 : u8; + let x173 : u8; + let x174 : u8; + let x175 : u8; + let x176 : u8; + let x177 : u8; + let x178 : u8; + let x179 : u8; + let x180 : u8; + let x181 : u8; + let x182 : u8; + let x183 : u8; + let x184 : u8; + let x185 : u8; + let x186 : u8; + let x187 : u8; + let x188 : u8; + let x189 : u8; + let x190 : u8; + let x191 : u8; + let x192 : u8; + let x193 : u8; + let x194 : u8; + let x195 : u8; + let x196 : u8; + let x197 : u8; + let x198 : u8; + let x199 : u8; + let x200 : u8; + let x201 : u8; + let x202 : u8; + let x203 : u8; + let x204 : u8; + let x205 : u8; + let x206 : u8; + let x207 : u8; + let x208 : u8; + let x209 : u8; + let x210 : u8; + let x211 : u8; + let x212 : u8; + let x213 : u8; + let x214 : u8; + let x215 : u8; + let x216 : u8; + let x217 : u8; + let x218 : u8; + let x219 : u8; + let x220 : u8; + let x221 : u8; + let x222 : u8; + let x223 : u8; + let x224 : u8; + let x225 : u8; + let x226 : u8; + let x227 : u8; + let x228 : u8; + let x229 : u8; + let x230 : u8; + let x231 : u8; + let x232 : u8; + let x233 : u8; + let x234 : u8; + let x235 : u8; + let x236 : u8; + let x237 : u8; + let x238 : u8; + let x239 : u8; + let x240 : u8; + let x241 : u8; + let x242 : u8; + let x243 : u8; + let x244 : u8; + let x245 : u8; + let x246 : u8; + let x247 : u8; + let x248 : u8; + let x249 : u8; + let x250 : u8; + let x251 : u8; + let x252 : u8; + let x253 : u8; + let x254 : u8; + let x255 : u8; + let x256 : u8; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_params.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_params.exp new file mode 100644 index 000000000..b62ab7bb9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_params.exp @@ -0,0 +1,4 @@ +processed 1 task + +task 0 'publish'. lines 1-264: +Error: value (256) cannot exceed (255) diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_params.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_params.mvir new file mode 100644 index 000000000..38cf0ef31 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/256_params.mvir @@ -0,0 +1,264 @@ +//# publish +module 0x1.M { + foo( + p1 : u8, + p2 : u8, + p3 : u8, + p4 : u8, + p5 : u8, + p6 : u8, + p7 : u8, + p8 : u8, + p9 : u8, + p10 : u8, + p11 : u8, + p12 : u8, + p13 : u8, + p14 : u8, + p15 : u8, + p16 : u8, + p17 : u8, + p18 : u8, + p19 : u8, + p20 : u8, + p21 : u8, + p22 : u8, + p23 : u8, + p24 : u8, + p25 : u8, + p26 : u8, + p27 : u8, + p28 : u8, + p29 : u8, + p30 : u8, + p31 : u8, + p32 : u8, + p33 : u8, + p34 : u8, + p35 : u8, + p36 : u8, + p37 : u8, + p38 : u8, + p39 : u8, + p40 : u8, + p41 : u8, + p42 : u8, + p43 : u8, + p44 : u8, + p45 : u8, + p46 : u8, + p47 : u8, + p48 : u8, + p49 : u8, + p50 : u8, + p51 : u8, + p52 : u8, + p53 : u8, + p54 : u8, + p55 : u8, + p56 : u8, + p57 : u8, + p58 : u8, + p59 : u8, + p60 : u8, + p61 : u8, + p62 : u8, + p63 : u8, + p64 : u8, + p65 : u8, + p66 : u8, + p67 : u8, + p68 : u8, + p69 : u8, + p70 : u8, + p71 : u8, + p72 : u8, + p73 : u8, + p74 : u8, + p75 : u8, + p76 : u8, + p77 : u8, + p78 : u8, + p79 : u8, + p80 : u8, + p81 : u8, + p82 : u8, + p83 : u8, + p84 : u8, + p85 : u8, + p86 : u8, + p87 : u8, + p88 : u8, + p89 : u8, + p90 : u8, + p91 : u8, + p92 : u8, + p93 : u8, + p94 : u8, + p95 : u8, + p96 : u8, + p97 : u8, + p98 : u8, + p99 : u8, + p100 : u8, + p101 : u8, + p102 : u8, + p103 : u8, + p104 : u8, + p105 : u8, + p106 : u8, + p107 : u8, + p108 : u8, + p109 : u8, + p110 : u8, + p111 : u8, + p112 : u8, + p113 : u8, + p114 : u8, + p115 : u8, + p116 : u8, + p117 : u8, + p118 : u8, + p119 : u8, + p120 : u8, + p121 : u8, + p122 : u8, + p123 : u8, + p124 : u8, + p125 : u8, + p126 : u8, + p127 : u8, + p128 : u8, + p129 : u8, + p130 : u8, + p131 : u8, + p132 : u8, + p133 : u8, + p134 : u8, + p135 : u8, + p136 : u8, + p137 : u8, + p138 : u8, + p139 : u8, + p140 : u8, + p141 : u8, + p142 : u8, + p143 : u8, + p144 : u8, + p145 : u8, + p146 : u8, + p147 : u8, + p148 : u8, + p149 : u8, + p150 : u8, + p151 : u8, + p152 : u8, + p153 : u8, + p154 : u8, + p155 : u8, + p156 : u8, + p157 : u8, + p158 : u8, + p159 : u8, + p160 : u8, + p161 : u8, + p162 : u8, + p163 : u8, + p164 : u8, + p165 : u8, + p166 : u8, + p167 : u8, + p168 : u8, + p169 : u8, + p170 : u8, + p171 : u8, + p172 : u8, + p173 : u8, + p174 : u8, + p175 : u8, + p176 : u8, + p177 : u8, + p178 : u8, + p179 : u8, + p180 : u8, + p181 : u8, + p182 : u8, + p183 : u8, + p184 : u8, + p185 : u8, + p186 : u8, + p187 : u8, + p188 : u8, + p189 : u8, + p190 : u8, + p191 : u8, + p192 : u8, + p193 : u8, + p194 : u8, + p195 : u8, + p196 : u8, + p197 : u8, + p198 : u8, + p199 : u8, + p200 : u8, + p201 : u8, + p202 : u8, + p203 : u8, + p204 : u8, + p205 : u8, + p206 : u8, + p207 : u8, + p208 : u8, + p209 : u8, + p210 : u8, + p211 : u8, + p212 : u8, + p213 : u8, + p214 : u8, + p215 : u8, + p216 : u8, + p217 : u8, + p218 : u8, + p219 : u8, + p220 : u8, + p221 : u8, + p222 : u8, + p223 : u8, + p224 : u8, + p225 : u8, + p226 : u8, + p227 : u8, + p228 : u8, + p229 : u8, + p230 : u8, + p231 : u8, + p232 : u8, + p233 : u8, + p234 : u8, + p235 : u8, + p236 : u8, + p237 : u8, + p238 : u8, + p239 : u8, + p240 : u8, + p241 : u8, + p242 : u8, + p243 : u8, + p244 : u8, + p245 : u8, + p246 : u8, + p247 : u8, + p248 : u8, + p249 : u8, + p250 : u8, + p251 : u8, + p252 : u8, + p253 : u8, + p254 : u8, + p255 : u8, + p256 : u8, + ) { + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals.exp new file mode 100644 index 000000000..6f873d8ae --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals.mvir new file mode 100644 index 000000000..0c94589d3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_few_type_actuals.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // missing type arg + let x: Self.S<>; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.exp new file mode 100644 index 000000000..6f873d8ae --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.mvir new file mode 100644 index 000000000..1ffbb5ded --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_bounds/too_many_type_actuals.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // type arg mismatch + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name.exp new file mode 100644 index 000000000..5495d3b88 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-7: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x1::M, + indices: [(FieldDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name.mvir new file mode 100644 index 000000000..382035942 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_field_name.mvir @@ -0,0 +1,7 @@ +//# publish +module 0x1.M { + // duplicate field of the same name + struct T{f: u64, f: u64} +} + +// check: DUPLICATE_ELEMENT diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_function_name.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_function_name.exp new file mode 100644 index 000000000..86db5c831 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_function_name.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_function_name.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_function_name.mvir new file mode 100644 index 000000000..0a1cd7d3b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_function_name.mvir @@ -0,0 +1,6 @@ +//# publish +module 0x42.M { + // duplicate functions + f() { label b0: } + f() { label b0: } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_struct_name.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_struct_name.exp new file mode 100644 index 000000000..cedea2736 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_struct_name.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x42::M, + indices: [(StructDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_struct_name.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_struct_name.mvir new file mode 100644 index 000000000..f766be9ff --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/duplicate_struct_name.mvir @@ -0,0 +1,6 @@ +//# publish +module 0x42.M { + // duplicate structs + struct T{b: bool} + struct T{x: u64} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_structs.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_structs.exp new file mode 100644 index 000000000..1f49c06d2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_structs.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::EmptyStruct'. Got VMError: { + major_status: ZERO_SIZED_STRUCT, + sub_status: None, + location: 0x1::EmptyStruct, + indices: [(StructDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_structs.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_structs.mvir new file mode 100644 index 000000000..5504e78c4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/empty_structs.mvir @@ -0,0 +1,6 @@ +//# publish +module 0x1.EmptyStruct { + // no empty structs allowed + struct Empty { } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/friend_decl_duplicated.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/friend_decl_duplicated.exp new file mode 100644 index 000000000..a0c4d8fa7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/friend_decl_duplicated.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'publish'. lines 5-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::B'. Got VMError: { + major_status: DUPLICATE_ELEMENT, + sub_status: None, + location: 0x42::B, + indices: [(ModuleHandle, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/friend_decl_duplicated.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/friend_decl_duplicated.mvir new file mode 100644 index 000000000..9c854cbab --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/check_duplication/friend_decl_duplicated.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x42.A { +} + +//# publish +module 0x42.B { + // duplicate friend decl + friend 0x42.A; + friend 0x42.A; +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_nested.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_nested.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_nested.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_nested.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_nested.mvir new file mode 100644 index 000000000..401d8a144 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_nested.mvir @@ -0,0 +1,23 @@ +//# run +module 0x42.m { +// check valid breaks in control flow check +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 0; + y = 0; +label while: + jump_if (false) while_cont; +label loop: + y = 5; + jump loop_cont; +label loop_cont: + x = 3; + jump while_cont; +label while_cont: + assert(move(x) == 3, 42); + assert(move(y) == 5, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_simple.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_simple.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_simple.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_simple.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_simple.mvir new file mode 100644 index 000000000..5c32d92f3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_simple.mvir @@ -0,0 +1,17 @@ +//# run +module 0x42.m { +// simple breaks for control flow check +entry foo() { + let x: u64; +label b0: + x = 0; +label while: + jump_if (false) while_cont; +label while_body: + x = move(x) + 1; + jump while_cont; +label while_cont: + assert(move(x) == 1, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_unreachable.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_unreachable.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_unreachable.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_unreachable.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_unreachable.mvir new file mode 100644 index 000000000..38f8b55f8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/break_unreachable.mvir @@ -0,0 +1,19 @@ +//# run +module 0x42.m { +// simple breaks for control flow check +entry foo() { + let x: u64; +label b0: + x = 1; +label while: + jump_if_false (true) while_cont; +label while_b0: + x = 3; + jump while_cont; + x = 5; + jump while_cont; +label while_cont: + assert(move(x) == 3, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return.mvir new file mode 100644 index 000000000..b2c9b2fbf --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return.mvir @@ -0,0 +1,25 @@ +//# publish + +// TODO: we might need to modify this test if we enable unreachable code +// checking in the verifier. + +module 0x1.Test { + public t(): u64 { + label b0: + return 100; + return 0; + } +} + +//# run +module 0x42.m { + +import 0x1.Test; +entry foo() { + let x: u64; +label b0: + x = Test.t(); + assert(copy(x) == 100, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return_local.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return_local.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return_local.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return_local.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return_local.mvir new file mode 100644 index 000000000..b0b66d84a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/dead_return_local.mvir @@ -0,0 +1,10 @@ +//# run +module 0x42.m { +// TODO: should the verifier allow dead code? +entry foo() { +label b0: + return; + assert(false, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_5.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_5.exp new file mode 100644 index 000000000..b1cf67793 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_5.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-18: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INDEX_OUT_OF_BOUNDS, + sub_status: None, + location: undefined, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 10)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_5.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_5.mvir new file mode 100644 index 000000000..ba1908cc3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_5.mvir @@ -0,0 +1,18 @@ +//# run +module 0x42.m { + +entry foo() { + let ret_if_val: bool; +label b0: + ret_if_val = true; + jump_if (move(ret_if_val)) loop; +label b1: + assert(false, 42); + return; +label loop: + jump loop_cont; + jump loop; +label loop_cont: +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_6.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_6.exp new file mode 100644 index 000000000..dda133494 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_6.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INDEX_OUT_OF_BOUNDS, + sub_status: None, + location: undefined, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 12)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_6.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_6.mvir new file mode 100644 index 000000000..fab3eff92 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_6.mvir @@ -0,0 +1,21 @@ +//# run +module 0x42.m { + +entry foo() { + let ret_if_val: bool; +label b0: + ret_if_val = true; + jump_if (move(ret_if_val)) loop; +label b1: + assert(false, 42); + return; +label loop: + jump_if (true) loop_b1; +label loop_b0: + jump loop_cont; +label loop_b1: + return; +label loop_cont: +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_8.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_8.exp new file mode 100644 index 000000000..7f94e2896 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_8.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-24: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INDEX_OUT_OF_BOUNDS, + sub_status: None, + location: undefined, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 15)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_8.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_8.mvir new file mode 100644 index 000000000..702eaa07c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/if_branch_diverges_8.mvir @@ -0,0 +1,24 @@ +//# run +module 0x42.m { + +entry foo() { + let ret_if_val: bool; +label b0: + ret_if_val = true; + jump_if (move(ret_if_val)) loop; +label b1: + assert(false, 42); + return; +label loop: + jump loop_cont; + jump_if (true) loop_b1; +label loop_b0: + jump loop; +label loop_b1: + return; +label loop_cont: + jump b2; +label b2: +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough1.exp new file mode 100644 index 000000000..736704a82 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough1.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-8: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EMPTY_CODE_UNIT, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough1.mvir new file mode 100644 index 000000000..478365205 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough1.mvir @@ -0,0 +1,8 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: // empty functions not allowed +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough2.exp new file mode 100644 index 000000000..949448a2b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough2.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INVALID_FALL_THROUGH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough2.mvir new file mode 100644 index 000000000..99c1d0890 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough2.mvir @@ -0,0 +1,12 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + return; + // invalid fall through + x = 7; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough3.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough3.exp new file mode 100644 index 000000000..bafbfc043 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough3.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INVALID_FALL_THROUGH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough3.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough3.mvir new file mode 100644 index 000000000..ff2660e9e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/invalid_fallthrough3.mvir @@ -0,0 +1,17 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + jump_if_false(true) b2; +label b1: + return; +label b2: + return; +label b3: + x = 7; + // invalid fall through +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_drop.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_drop.exp new file mode 100644 index 000000000..14e08fc1d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_drop.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 17-5497: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 65530)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_drop.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_drop.mvir new file mode 100644 index 000000000..1040e474d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_drop.mvir @@ -0,0 +1,5497 @@ +//# publish +module 0x1.test { + struct HotPotato { value: u64 } + public get_hot_potato(): Self.HotPotato { + label l0: + return HotPotato { value: 42 }; + } + + public destroy_hot_potato(potato: Self.HotPotato) { + label l0: + HotPotato {} = move(potato); + _ = (); + return; + } +} + +//# run +module 0x42.m { +import 0x1.test; +// check valid breaks in control flow check +entry foo() { + let hot_potato_1: test.HotPotato; + let hot_potato_2: test.HotPotato; +label start: + jump end; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; +label code: + hot_potato_1 = test.get_hot_potato(); + hot_potato_2 = test.get_hot_potato(); + hot_potato_1 = move(hot_potato_2); + test.destroy_hot_potato(move(hot_potato_1)); + return; +label end: + jump code; + +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_reference.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_reference.exp new file mode 100644 index 000000000..28246cbe4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_reference.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-5480: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 65529)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_reference.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_reference.mvir new file mode 100644 index 000000000..c21c3f68f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/last_jump_unconditional_reference.mvir @@ -0,0 +1,5480 @@ +//# run +module 0x42.m { +// check valid breaks in control flow check +entry foo() { + let v: vector; + let vref: &mut vector; + let r: &mut u64; +label start: + jump end; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; return; return; + return; return; return; return; return; return; return; return; return; return; +label code: + v = vec_pack_1(0); + vref = &mut v; + r = vec_mut_borrow(copy(vref), 0); + _ = vec_pop_back(copy(vref)); + *copy(r) = 1; +label end: + jump code; + +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_496.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_496.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_496.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_496.move b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_496.move new file mode 100644 index 000000000..d17230674 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_496.move @@ -0,0 +1,18 @@ +//# publish +module 0x42::test_case { + public fun test_loop(a: u64): u64 { + if (a == 2) { + 1 + } else if (a == 3) { + let i = 0; + let ret = 0; + while (i < a) { + ret = ret + i; + i = i + 1; + }; + ret + } else { + abort 10000 + } + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_678.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_678.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_678.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_678.move b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_678.move new file mode 100644 index 000000000..cba6f8098 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/control_flow/regression_test_678.move @@ -0,0 +1,22 @@ +//# publish +module 0x42::test_case { + struct Foo has drop {} + + fun bar(_foo: &mut Foo) { + /* ... */ + } + + fun remove_tx(foo: &mut Foo) { + let i = 0; + while (i < 64) { + i = i + 1; + + bar(foo); + if (i < 30) { + continue + }; + + break + } + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_friend_function_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_friend_function_invalid.exp new file mode 100644 index 000000000..c08c13cd9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_friend_function_invalid.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'publish'. lines 9-18: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::N'. Got VMError: { + major_status: LOOKUP_FAILED, + sub_status: None, + location: 0x42::N, + indices: [(FunctionHandle, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_friend_function_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_friend_function_invalid.mvir new file mode 100644 index 000000000..e26c71e3e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_friend_function_invalid.mvir @@ -0,0 +1,18 @@ +//# publish +module 0x42.M { + public(friend) foo() { + label b0: + return; + } +} + +//# publish +module 0x42.N { + import 0x42.M; + foo() { + label b0: + // cannot call friend visible function if not a friend + M.foo(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_private_function.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_private_function.exp new file mode 100644 index 000000000..06fdb10b9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_private_function.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 9-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: LOOKUP_FAILED, + sub_status: None, + location: 0x42::m, + indices: [(FunctionHandle, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_private_function.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_private_function.mvir new file mode 100644 index 000000000..d76019508 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_private_function.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x42.M { + universal_truth(): u64 { + label b0: + return 42; + } +} + +//# run +module 0x42.m { +import 0x42.M; + +entry foo() { + let x: u64; +label b0: + // cannot call private/internal functions + x = M.universal_truth(); + return; +} +} + +// check: LOOKUP_FAILED diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_public_function.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_public_function.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_public_function.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_public_function.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_public_function.mvir new file mode 100644 index 000000000..c66388b7b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/access_public_function.mvir @@ -0,0 +1,20 @@ +//# publish +module 0x42.M { + public universal_truth(): u64 { + label b0: + return 42; + } +} + +//# run +module 0x42.m { +import 0x42.M; + +entry foo() { + let x: u64; +label b0: + // can call public functions + x = M.universal_truth(); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/all_fields_accessible.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/all_fields_accessible.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/all_fields_accessible.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/all_fields_accessible.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/all_fields_accessible.mvir new file mode 100644 index 000000000..60938fe8d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/all_fields_accessible.mvir @@ -0,0 +1,76 @@ +//# publish +module 0x42.M { + struct A{x: u64} + struct B has drop {y: u64} + + public a(x: u64): Self.A { + label b0: + return A{x: move(x)}; + } + + public b(y: u64): Self.B { + label b0: + return B{y: move(y)}; + } + + public set_a_with_b(a: &mut Self.A, b: &Self.B) { + let x_ref: &mut u64; + let y_ref: &u64; + label b0: + x_ref = &mut copy(a).A::x; + y_ref = ©(b).B::y; + *move(x_ref) = *move(y_ref); + _ = move(a); + _ = move(b); + return; + } + + public set_b_with_a(b: &mut Self.B, a: &Self.A) { + let x_ref: &u64; + let y_ref: &mut u64; + label b0: + y_ref = &mut copy(b).B::y; + x_ref = ©(a).A::x; + *move(y_ref) = *move(x_ref); + _ = move(a); + _ = move(b); + return; + } + + public destroy_a(a: Self.A) { + let x: u64; + label b0: + A{ x } = move(a); + return; + } +} + +//# run +module 0x42.m { +import 0x42.M; + +entry foo() { + let a: M.A; + let a_ref: &M.A; + let a_mut_ref: &mut M.A; + let b: M.B; + let b_ref: &M.B; + let b_mut_ref: &mut M.B; +label b0: + a = M.a(0); + b = M.b(1); + + a_mut_ref = &mut a; + b_ref = &b; + // can call public functions + M.set_a_with_b(move(a_mut_ref), move(b_ref)); + + a_ref = &a; + b_mut_ref = &mut b; + M.set_b_with_a(move(b_mut_ref), move(a_ref)); + + M.destroy_a(move(a)); + + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.move b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.move new file mode 100644 index 000000000..96a8df310 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/call_integers_valid.move @@ -0,0 +1,22 @@ +//# publish +module 0x42::m { +public fun plus8(a: u8): u8 { a + 1 } +public fun plus16(a: u16): u16 { a + 1 } +public fun plus32(a: u32): u32 { a + 1 } +public fun plus64(a: u64): u64 { a + 1 } +public fun plus128(a: u128): u128 { a + 1 } +public fun plus256(a: u256): u256 { a + 1 } +} + + +//# publish +module 0x42::m_test { +use 0x42::m; +public fun test8() { m::plus8(1u8); } +public fun test16() { m::plus16(1u16); } +public fun test32() { m::plus32(1u32); } +public fun test64() { m::plus64(1u64); } +public fun test128() { m::plus128(1u128); } +public fun test256() { m::plus256(1u256); } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/internal_function_invalid_call.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/internal_function_invalid_call.exp new file mode 100644 index 000000000..4d389f1f2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/internal_function_invalid_call.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 41-56: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CALL_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/internal_function_invalid_call.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/internal_function_invalid_call.mvir new file mode 100644 index 000000000..07ba3ffff --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/internal_function_invalid_call.mvir @@ -0,0 +1,56 @@ +//# publish +module 0x42.Test { + struct T has drop {value: u64} + + initial_value(): u64 { + label b0: + return 42; + } + + public new(): Self.T { + let initial_value: u64; + label b0: + initial_value = Self.initial_value(); + return T{value: move(initial_value)}; + } + + public get_value(this: &Self.T): u64 { + let x: &u64; + label b0: + x = ©(this).T::value; + _ = move(this); + return *move(x); + } + + public set_value(this: &mut Self.T, new_value: u64) { + label b0: + Self.internal_set_value(move(this), move(new_value)); + return; + } + + internal_set_value(this: &mut Self.T, new_value: u64) { + let x: &mut u64; + label b0: + x = &mut copy(this).T::value; + *move(x) = move(new_value); + _ = move(this); + return; + } +} + +//# run +module 0x42.m { +import 0x42.Test; + +entry foo() { + let obj: Test.T; + let ref: &Test.T; +label b0: + obj = Test.new(); + ref = &obj; + // calling an internal function with the wrong arguments will fail before visibility checks + // are done + Test.internal_set_value(move(ref), 1); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/non_internal_function_valid_call.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/non_internal_function_valid_call.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/non_internal_function_valid_call.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/non_internal_function_valid_call.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/non_internal_function_valid_call.mvir new file mode 100644 index 000000000..c976ee669 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/non_internal_function_valid_call.mvir @@ -0,0 +1,56 @@ +//# publish +module 0x42.Test { + struct T has drop {value: u64} + + initial_value(): u64 { + label b0: + return 42; + } + + public new(): Self.T { + let initial_value: u64; + label b0: + initial_value = Self.initial_value(); + return T{value: move(initial_value)}; + } + + public get_value(this: &Self.T): u64 { + let x: &u64; + label b0: + x = ©(this).T::value; + _ = move(this); + return *move(x); + } + + public set_value(this: &mut Self.T, new_value: u64) { + label b0: + Self.internal_set_value(move(this), move(new_value)); + return; + } + + internal_set_value(this: &mut Self.T, new_value: u64) { + let x: &mut u64; + label b0: + x = &mut copy(this).T::value; + *move(x) = move(new_value); + _ = move(this); + return; + } +} + +//# run +module 0x42.m { +import 0x42.Test; + +entry foo() { + let obj: Test.T; + let ref: &Test.T; + let val: u64; +label b0: + obj = Test.new(); + ref = &obj; + val = Test.get_value(move(ref)); + + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/use_unpublished_module.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/use_unpublished_module.exp new file mode 100644 index 000000000..436ffccd0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/use_unpublished_module.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: LINKER_ERROR, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/use_unpublished_module.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/use_unpublished_module.mvir new file mode 100644 index 000000000..6b7706c82 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/dependencies/use_unpublished_module.mvir @@ -0,0 +1,10 @@ +//# run +module 0x42.m { +// missing dep +import 0x42.M; + +entry foo() { +label b0: + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_different_address.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_different_address.exp new file mode 100644 index 000000000..233693e52 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_different_address.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'publish'. lines 5-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000044::N'. Got VMError: { + major_status: INVALID_FRIEND_DECL_WITH_MODULES_OUTSIDE_ACCOUNT_ADDRESS, + sub_status: None, + location: 0x44::N, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_different_address.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_different_address.mvir new file mode 100644 index 000000000..51a1578a1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_different_address.mvir @@ -0,0 +1,9 @@ +//# publish +module 0x43.M { +} + +//# publish +module 0x44.N { + // friends must be in the same address + friend 0x43.M; +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_self.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_self.exp new file mode 100644 index 000000000..1cf0800e8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_self.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-5: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INVALID_FRIEND_DECL_WITH_SELF, + sub_status: None, + location: 0x42::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_self.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_self.mvir new file mode 100644 index 000000000..ae0208cd2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/friends/friend_decl_self.mvir @@ -0,0 +1,5 @@ +//# publish +module 0x42.M { + // cannot be a friend with yourself + friend 0x42.M; +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.exp new file mode 100644 index 000000000..88822b962 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.exp @@ -0,0 +1,28 @@ +processed 3 tasks + +task 0 'publish'. lines 1-51: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} + +task 1 'publish'. lines 53-70: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M2, + indices: [], + offsets: [], +} + +task 2 'publish'. lines 72-122: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M3, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.mvir new file mode 100644 index 000000000..338a67ae2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/complex_1.mvir @@ -0,0 +1,122 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + a() { + label b0: + Self.b, u64>(); + return; + } + + b() { + label b0: + Self.f(); + Self.c, bool>(); + return; + } + + c() { + label b0: + Self.c(); + Self.d(); + Self.e(); + return; + } + + d() { + label b0: + Self.b(); + return; + } + + e() { + label b0: + return; + } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.f>(); + return; + } +} +// There are two disjoint loops in the resulting graph, but only one error +// loop: f#T --> g#T --S--> f#T +// loop: c#T1 --> c#T2 --> d#T --> b#T2 --S--> c#T1 + +//# publish +module 0x1.M2 { + struct S { b: bool } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.f>(); + return; + } +} +// loop: f#T --> g#T --S--> f#T +// check: LOOP_IN_INSTANTIATION_GRAPH + +//# publish + +module 0x1.M3 { + struct S { b: bool } + + a() { + label b0: + Self.b, u64>(); + return; + } + + b() { + label b0: + Self.f(); + Self.c, bool>(); + return; + } + + c() { + label b0: + Self.c(); + Self.d(); + Self.e(); + return; + } + + d() { + label b0: + Self.b(); + return; + } + + e() { + label b0: + return; + } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + // Switched to just to isolate the loop + Self.f(); + return; + } +} +// loop: c#T1 --> c#T2 --> d#T --> b#T2 --S--> c#T1 diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.mvir new file mode 100644 index 000000000..e629305a0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_just_type_params_ok.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.M { + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.mvir new file mode 100644 index 000000000..36b0e3d5d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_non_generic_type_ok.mvir @@ -0,0 +1,16 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + f() { + label b0: + Self.g>(); + return; + } + + g() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.mvir new file mode 100644 index 000000000..35f8a8925 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_just_type_params_shitfing_ok.mvir @@ -0,0 +1,20 @@ +//# publish +module 0x1.M { + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.h(); + return; + } + + h() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.mvir new file mode 100644 index 000000000..d351f5297 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_non_generic_types_ok.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.h>(); + return; + } + + h() { + label b0: + // The bool breaks the chain. + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp new file mode 100644 index 000000000..3b9f372de --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.mvir new file mode 100644 index 000000000..8633f2a89 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_three_args_type_con_shifting.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + // indirect loop (takes a while) + Self.h>(); + return; + } + + h() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.mvir new file mode 100644 index 000000000..b829f04b1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_non_generic_type_and_type_param_ok.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.M { + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.mvir new file mode 100644 index 000000000..fdd12bf42 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_just_type_params_ok.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.M { + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp new file mode 100644 index 000000000..6457e989d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.mvir new file mode 100644 index 000000000..39bfec96c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_two_args_swapping_type_con.mvir @@ -0,0 +1,17 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + f() { + label b0: + Self.g(); + return; + } + + g() { + label b0: + // indirect loop with swap + Self.f>(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp new file mode 100644 index 000000000..e68aa0a00 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.mvir new file mode 100644 index 000000000..17d06014e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/mutually_recursive_type_con.mvir @@ -0,0 +1,20 @@ +//# publish + +// Not good: infinitely many types/instances. +// f, g>, f>, g>>, ... + +module 0x1.M { + struct S { b: bool } + + f() { + label b0: + Self.g>(); + return; + } + + g() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1.exp new file mode 100644 index 000000000..011ac8091 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1.mvir new file mode 100644 index 000000000..0dded5ba1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_1.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + label b0: + // loop + Self.foo>>(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.exp new file mode 100644 index 000000000..e7a1ab8d9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.mvir new file mode 100644 index 000000000..8d0b0a070 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/nested_types_2.mvir @@ -0,0 +1,13 @@ +//# publish + +module 0x1.M { + struct S { b: bool } + struct R { b: bool } + + foo() { + label b0: + // instantiation loop + Self.foo>>>(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp new file mode 100644 index 000000000..f4a66de93 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-45: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.mvir new file mode 100644 index 000000000..a2847b039 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_infinite_type_terminates.mvir @@ -0,0 +1,45 @@ +//# publish + +module 0x1.M { + struct Box { x: T } + + unbox(b: Self.Box): T { + let x: T; + label b0: + Box { x: x } = move(b); + return move(x); + } + + f(n: u64, x: T): T { + label b0: + jump_if (copy(n) == 0) b2; + label b1: + return Self.unbox(Self.f>(copy(n) - 1, Box { x: move(x) })); + label b2: + return move(x); + } +} + +// Function f calls an instance of itself instantiated with a boxed type, but it does +// terminate properly if we allow new types to be created on the fly. +// +// As reference, the equivalent Haskell code compiles & terminates: +// +// data Boxed a = Box a +// +// unbox (Box a) = a +// +// f :: Integer -> a -> a +// f 0 x = x +// f n x = unbox (f (n-1) (Box x)) +// +// main = do +// let x = 42 +// putStrLn (show (f 5 x)) +// +// Without the annotation f :: Integer -> a -> a GHC complains about not being able to +// construct the infinite type a ~ Boxed a. +// +// We are taking a conservative approach and forbids such construction in move. + +// check: LOOP_IN_INSTANTIATION_GRAPH diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.mvir new file mode 100644 index 000000000..2e4b63f44 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_just_type_params_ok.mvir @@ -0,0 +1,11 @@ +//# publish + +// This is good as there is only one instance foo for any T. + +module 0x1.M { + f(x: T) { + label b0: + Self.f(move(x)); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.mvir new file mode 100644 index 000000000..52d442efd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_non_generic_type_ok.mvir @@ -0,0 +1,11 @@ +//# publish + +// Good: two instances foo & foo (if T != u64) for any T. + +module 0x1.M { + f() { + label b0: + Self.f(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp new file mode 100644 index 000000000..e7a1ab8d9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.mvir new file mode 100644 index 000000000..0bf3a7ece --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_one_arg_type_con.mvir @@ -0,0 +1,13 @@ +//# publish + +// Bad! Can have infinitely many instances: f, f>, f>>, ... + +module 0x1.M { + struct S { b: bool } + + f(x: T) { + label b0: + Self.f>(S { b: true }); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.exp new file mode 100644 index 000000000..2d8767257 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.mvir new file mode 100644 index 000000000..f9baf2ac9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/recursive_two_args_swapping_type_con.mvir @@ -0,0 +1,14 @@ +//# publish + +// Similar to the case with one argument, but swaps the two type parameters. +// f => f, T1> => f, S> => f>, S> => ... + +module 0x1.M { + struct S { x: T } + + f(a: T1, b: T2) { + label b0: + Self.f, T1>(S { x: move(b) }, move(a)); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.exp new file mode 100644 index 000000000..e68aa0a00 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: LOOP_IN_INSTANTIATION_GRAPH, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.mvir new file mode 100644 index 000000000..1c553a73f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/instantiation_loops/two_loops.mvir @@ -0,0 +1,20 @@ +//# publish + +// Two loops in the resulting graph. +// One error for the loop. + +module 0x1.M { + struct S { b: bool } + + f() { + label b0: + Self.f>(); + return; + } + + g() { + label b0: + Self.g>(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unreleased_reference.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unreleased_reference.exp new file mode 100644 index 000000000..4491ec255 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unreleased_reference.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-13: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unreleased_reference.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unreleased_reference.mvir new file mode 100644 index 000000000..b3ac1383f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unreleased_reference.mvir @@ -0,0 +1,13 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let x_ref: &mut u64; +label b0: + x = 0; + x_ref = &mut x; + abort 0; // x_ref does not have to be released +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unused_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unused_resource.exp new file mode 100644 index 000000000..24aa88e99 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unused_resource.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 10-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: LOOKUP_FAILED, + sub_status: None, + location: 0x42::m, + indices: [(FunctionHandle, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unused_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unused_resource.mvir new file mode 100644 index 000000000..c8bea4804 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/abort_unused_resource.mvir @@ -0,0 +1,20 @@ +//# publish +module 0x1.M { + struct Coin { value: u64 } + zero(): Self.Coin { + label b0: + return Coin { value: 0 }; + } +} + +//# run +module 0x42.m { +import 0x1.M; + +entry foo() { + let z: M.Coin; +label b0: + z = M.zero(); + abort 0; // valid that z is unused +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_copy.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_copy.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_copy.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_copy.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_copy.mvir new file mode 100644 index 000000000..16347e102 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_copy.mvir @@ -0,0 +1,16 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 5; + // valid copy + y = copy(x); + // valid copy + assert(copy(y) == 5, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_in_one_if_branch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_in_one_if_branch.exp new file mode 100644 index 000000000..894758b06 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_in_one_if_branch.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 14)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_in_one_if_branch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_in_one_if_branch.mvir new file mode 100644 index 000000000..d1584a65f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_in_one_if_branch.mvir @@ -0,0 +1,23 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + jump_if (true) b2; +label b1: + assert(false, 42); + jump b3; +label b2: + x = 5; +label b3: + jump_if_false (true) b5; +label b4: + y = 5; +label b5: + assert(copy(x) == copy(y), 42); // invalid copy + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_move.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_move.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_move.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_move.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_move.mvir new file mode 100644 index 000000000..3936c6943 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_move.mvir @@ -0,0 +1,16 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 5; + // valid move + y = move(x); + // valid copy + assert(copy(y) == 5, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_resource.exp new file mode 100644 index 000000000..e729363f8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_resource.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 10-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_resource.mvir new file mode 100644 index 000000000..024843695 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_resource.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x1.M { + struct Coin { value: u64 } + zero(): Self.Coin { + label b0: + return Coin { value: 0 }; + } +} + +//# run +module 0x42.m { +import 0x1.M; + +entry foo() { + let z: M.Coin; +label b0: + z = M.zero(); + // invalid assignment + z = M.zero(); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch.exp new file mode 100644 index 000000000..c73237577 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 10)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch.mvir new file mode 100644 index 000000000..a14a23824 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch.mvir @@ -0,0 +1,19 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + jump_if (true) b2; +label b1: + x = 100; + jump b3; +label b2: + assert(true, 42); +label b3: + // invalid copy + assert(copy(x) == 100, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.exp new file mode 100644 index 000000000..879f45604 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-15: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.mvir new file mode 100644 index 000000000..02b698ebf --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/assign_wrong_if_branch_no_else.mvir @@ -0,0 +1,15 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + jump_if_false (false) b2; +label b1: + x = 100; +label b2: + assert(copy(x) == 100, 42); // invalid copy + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves.exp new file mode 100644 index 000000000..7e91deac1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 9)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves.mvir new file mode 100644 index 000000000..16bb0817d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves.mvir @@ -0,0 +1,21 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + jump_if (true) b2; +label b1: + x = 0; + jump b3; +label b2: + x = 1; + y = move(x); +label b3: + // invalid copy + assert(copy(x) == 5, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.mvir new file mode 100644 index 000000000..09bd1097f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/branch_assigns_then_moves_then_assigns.mvir @@ -0,0 +1,22 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + jump_if (true) b2; +label b1: + x = 0; + jump b3; +label b2: + x = 1; + y = move(x); + x = 5; +label b3: + // valid copy + assert(copy(x) == 5, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.mvir new file mode 100644 index 000000000..20ba08c19 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/deep_return_branch_doesnt_assign.mvir @@ -0,0 +1,23 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + jump_if (true) b2; +label b1: + x = 0; + jump b5; +label b2: + jump_if (false) b4; +label b3: + return; +label b4: + return; +label b5: + // valid copy, other branches return + assert(copy(x) == 5, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_assigns_if_doesnt.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_assigns_if_doesnt.exp new file mode 100644 index 000000000..cc589d4ca --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_assigns_if_doesnt.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 7)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_assigns_if_doesnt.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_assigns_if_doesnt.mvir new file mode 100644 index 000000000..5e2ace86c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_assigns_if_doesnt.mvir @@ -0,0 +1,20 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + jump_if (true) b2; +label b1: + x = 42; + jump b3; +label b2: + y = 0; +label b3: + // invalid copy + assert(copy(y) == 0, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_moves_if_doesnt.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_moves_if_doesnt.exp new file mode 100644 index 000000000..7e91deac1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_moves_if_doesnt.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 9)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_moves_if_doesnt.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_moves_if_doesnt.mvir new file mode 100644 index 000000000..27120d943 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/else_moves_if_doesnt.mvir @@ -0,0 +1,21 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 0; + jump_if (true) b2; +label b1: + y = move(x); + jump b3; +label b2: + y = 0; +label b3: + // invalid copy + assert(copy(x) == 0, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_else_doesnt.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_else_doesnt.exp new file mode 100644 index 000000000..cc589d4ca --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_else_doesnt.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 7)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_else_doesnt.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_else_doesnt.mvir new file mode 100644 index 000000000..ae7f10a5d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_else_doesnt.mvir @@ -0,0 +1,20 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + jump_if (true) b2; +label b1: + y = 0; + jump b3; +label b2: + x = 42; +label b3: + // invalid copy + assert(copy(x) == 42, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_no_else.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_no_else.exp new file mode 100644 index 000000000..ae079aad7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_no_else.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-16: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_no_else.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_no_else.mvir new file mode 100644 index 000000000..4033a4578 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_assigns_no_else.mvir @@ -0,0 +1,16 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + jump_if_false (true) b2; +label b1: + x = 42; +label b2: + // invalid copy, might not have a value + assert(copy(x) == 42, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_else_doesnt.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_else_doesnt.exp new file mode 100644 index 000000000..7e91deac1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_else_doesnt.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 9)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_else_doesnt.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_else_doesnt.mvir new file mode 100644 index 000000000..9fe6ddb52 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_else_doesnt.mvir @@ -0,0 +1,21 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 0; + jump_if (true) b2; +label b1: + y = 0; + jump b3; +label b2: + y = move(x); +label b3: + // invalid copy, might not have a value + assert(copy(x) == 0, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_no_else.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_no_else.exp new file mode 100644 index 000000000..5d4753bd9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_no_else.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-18: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_no_else.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_no_else.mvir new file mode 100644 index 000000000..c5936dab4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/if_moves_no_else.mvir @@ -0,0 +1,18 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 0; + jump_if_false (true) b2; +label b1: + y = move(x); +label b2: + // invalid copy + assert(copy(x) == 0, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/join_failure.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/join_failure.exp new file mode 100644 index 000000000..8fb0fb20b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/join_failure.exp @@ -0,0 +1,46 @@ +processed 5 tasks + +task 0 'publish'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: MOVELOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 15)], +} + +task 1 'publish'. lines 22-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 15)], +} + +task 2 'publish'. lines 42-61: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 17)], +} + +task 3 'publish'. lines 63-82: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 15)], +} + +task 4 'publish'. lines 84-104: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: BORROWLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 15)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/join_failure.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/join_failure.mvir new file mode 100644 index 000000000..116fd6161 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/join_failure.mvir @@ -0,0 +1,104 @@ +//# publish +module 0x1.M { + struct R { f:bool } + t0() { + let r: Self.R; + let f: bool; + label b0: + r = R{ f: false }; + jump_if (true) b2; + label b1: + R{ f: f } = move(r); + r = R{ f: false }; + jump b3; + label b2: + R{ f: f } = move(r); + label b3: + R{ f: f } = move(r); // invalid move loc + return; + } +} + +//# publish +module 0x1.M { + struct R { f:bool } + t0() { + let r: Self.R; + let f: bool; + label b0: + r = R{ f: false }; + jump_if (true) b2; + label b1: + R{ f: f } = move(r); + r = R{ f: false }; + jump b3; + label b2: + R{ f: f } = move(r); + label b3: + return; // resource unused + } +} + +//# publish +module 0x1.M { + struct R { f:bool } + t0() { + let r: Self.R; + let f: bool; + label b0: + r = R{ f: false }; + jump_if (true) b2; + label b1: + R{ f: f } = move(r); + r = R{ f: false }; + jump b3; + label b2: + R{ f: f } = move(r); + label b3: + r = R{ f: false }; // invalid, still possibly a resource in r + return; + } +} + +//# publish +module 0x1.M { + struct R has copy, drop { f:bool } + t0() { + let r: Self.R; + let f: bool; + label b0: + r = R{ f: false }; + jump_if (true) b2; + label b1: + R{ f: f } = move(r); + r = R{ f: false }; + jump b3; + label b2: + R{ f: f } = move(r); + label b3: + R{ f: f } = copy(r); // invalid copy, r might not have a value + return; + } +} + +//# publish +module 0x1.M { + struct R { f:bool } + t0() { + let r: Self.R; + let ref: &Self.R; + let f: bool; + label b0: + r = R{ f: false }; + jump_if (true) b2; + label b1: + R{ f: f } = move(r); + r = R{ f: false }; + jump b3; + label b2: + R{ f: f } = move(r); + label b3: + ref = &r; // cannot borrow, might not have a value + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/move_before_assign.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/move_before_assign.exp new file mode 100644 index 000000000..628f6042d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/move_before_assign.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/move_before_assign.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/move_before_assign.mvir new file mode 100644 index 000000000..a9d0ca907 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/move_before_assign.mvir @@ -0,0 +1,14 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + // invalid move + y = move(x); + return; +} + +} +// check: MOVELOC_UNAVAILABLE_ERROR diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_doesnt_assign.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_doesnt_assign.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_doesnt_assign.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_doesnt_assign.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_doesnt_assign.mvir new file mode 100644 index 000000000..f934b27b7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_doesnt_assign.mvir @@ -0,0 +1,18 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + jump_if (true) b2; +label b1: + x = 0; + jump b3; +label b2: + return; +label b3: + assert(copy(x) == 5, 42); // okay to use x + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_moves.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_moves.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_moves.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_moves.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_moves.mvir new file mode 100644 index 000000000..aca77a5bc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/return_branch_moves.mvir @@ -0,0 +1,19 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 0; + jump_if (false) b2; +label b1: + // okay to use x + assert(copy(x) == 0, 42); + return; +label b2: + y = move(x); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_st_loc_partial.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_st_loc_partial.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_st_loc_partial.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_st_loc_partial.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_st_loc_partial.mvir new file mode 100644 index 000000000..3475be2ad --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_st_loc_partial.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x42.M { + consume(s: signer) { + label b0: + Self.consume(move(s)); + return; + } + + t(cond: bool, s1: signer, s2: signer) { + label b0: + jump_if_false (move(cond)) b2; + label b1: + Self.consume(move(s1)); + label b2: + s1 = move(s2); + Self.consume(move(s1)); + return; + } +} + +// Used to be invalid +// Now valid because signer has drop diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused.mvir new file mode 100644 index 000000000..4d9678e55 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x42.M { + t(s: signer) { + label b0: + return; + } +} + +// Used to be invalid +// Now valid because signer has drop diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused_partial.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused_partial.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused_partial.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused_partial.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused_partial.mvir new file mode 100644 index 000000000..68fdbc108 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/signer_unused_partial.mvir @@ -0,0 +1,20 @@ +//# publish +module 0x42.M { + consume(s: signer) { + label b0: + Self.consume(move(s)); + return; + } + + t(cond: bool, s: signer) { + label b0: + jump_if_false (move(cond)) b2; + label b1: + Self.consume(move(s)); + label b2: + return; + } +} + +// Used to be invalid +// Now valid because signer has drop diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/use_before_assign.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/use_before_assign.exp new file mode 100644 index 000000000..3dfc9e9dd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/use_before_assign.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: COPYLOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/use_before_assign.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/use_before_assign.mvir new file mode 100644 index 000000000..9e09b5a40 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/use_before_assign.mvir @@ -0,0 +1,13 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + // invalid copy + y = copy(x); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.exp new file mode 100644 index 000000000..7a8a07c5b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.mvir new file mode 100644 index 000000000..d025af3e1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/vector_ops_non_droppable_resource_not_destroyed.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x1.M { + struct R has store { b: bool } + f() { + let v: vector; + label b0: + v = vec_pack_0(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local.exp new file mode 100644 index 000000000..2fba20f57 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local.mvir new file mode 100644 index 000000000..80ab85dfd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local.mvir @@ -0,0 +1,23 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; + let b: bool; +label b0: + x = 0; + b = true; +label while: + jump_if_false (copy(b)) while_cont; +label while_body: + y = move(x); + b = false; + jump while; +label while_cont: + // invalid move + assert(move(y) == 0, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local_2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local_2.exp new file mode 100644 index 000000000..ee5528dbf --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local_2.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-27: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local_2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local_2.mvir new file mode 100644 index 000000000..3a5d266ae --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/locals_safety/while_move_local_2.mvir @@ -0,0 +1,27 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; + let b: bool; +label b0: + x = 0; + b = true; +label while: + jump_if_false (true) while_cont; +label while_b0: + jump_if (copy(b)) while_b2; +label while_b1: + x = move(y); // invalid move + jump while_b3; +label while_b2: + y = move(x); +label while_b3: + b = false; + jump while; +label while_cont: + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_field_after_local.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_field_after_local.exp new file mode 100644 index 000000000..56a1524b0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_field_after_local.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { + major_status: WRITEREF_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::Tester, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_field_after_local.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_field_after_local.mvir new file mode 100644 index 000000000..88370ec00 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_field_after_local.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x42.Tester { + struct T has drop {v: u64} + + public new(v: u64): Self.T { + label b0: + return T{v: move(v)}; + } + + public replace(t: &mut Self.T) { + let t_v: &mut u64; + let new_t: Self.T; + label b0: + t_v = &mut copy(t).T::v; + new_t = Self.new(1); + // cannot mutate, still borrowed + *move(t) = move(new_t); + + *move(t_v) = 10000; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_after_move.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_after_move.exp new file mode 100644 index 000000000..ea6e41089 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_after_move.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 12)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_after_move.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_after_move.mvir new file mode 100644 index 000000000..3cbd74df1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_after_move.mvir @@ -0,0 +1,17 @@ +//# run +module 0x42.m { + +entry foo() { + let v: u64; + let ref_v: &mut u64; + let dead: u64; +label b0: + v = 5; + ref_v = &mut v; + assert(*copy(ref_v) == 5, 42); + dead = move(v); // cannot move local, still borrowed + *move(ref_v) = 42; + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct.mvir new file mode 100644 index 000000000..dfa095a5b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct.mvir @@ -0,0 +1,56 @@ +//# publish +module 0x42.Tester { + struct T has drop {v: u64} + + public new(v: u64): Self.T { + label b0: + return T{v: move(v)}; + } + + public replace(t: &mut Self.T) { + let t2: &mut Self.T; + let t_v: &mut u64; + let new_t: Self.T; + label b0: + t2 = copy(t); + t_v = &mut copy(t2).T::v; + *move(t_v) = 10000; + + new_t = Self.new(1); + *move(t2) = move(new_t); + _ = move(t); + return; + } + + public value(this: &mut Self.T): u64 { + let ref_v: &u64; + label b0: + ref_v = &move(this).T::v; + return *move(ref_v); + } + +} + +//# run +module 0x42.m { +import 0x42.Tester; + +entry foo() { + let t: Tester.T; + let ref_t: &mut Tester.T; + let v_from_ref: u64; + let tt: &mut Tester.T; + let v_from_t: u64; +label b0: + t = Tester.new(0); + ref_t = &mut t; + // valid as this is the only reference to t + Tester.replace(copy(ref_t)); + v_from_ref = Tester.value(move(ref_t)); + tt = &mut t; + v_from_t = Tester.value(move(tt)); + assert(copy(v_from_ref) == 1, 42); + assert(copy(v_from_t) == 1, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct_invalidated.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct_invalidated.exp new file mode 100644 index 000000000..58495357d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct_invalidated.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 36-63: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct_invalidated.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct_invalidated.mvir new file mode 100644 index 000000000..a245464ed --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_struct_invalidated.mvir @@ -0,0 +1,63 @@ +//# publish +module 0x42.Tester { + struct T has drop {v: u64} + + public new(v: u64): Self.T { + label b0: + return T{v: move(v)}; + } + + public replace(t: &mut Self.T) { + let t2: &mut Self.T; + let t_v: &mut u64; + let new_t: Self.T; + label b0: + t2 = copy(t); + t_v = &mut copy(t2).T::v; + *move(t_v) = 10000; + new_t = Self.new(1); + *move(t2) = move(new_t); + _ = move(t); + return; + } + + public value(this: &mut Self.T): u64 { + let ref_v: &u64; + let r: u64; + label b0: + ref_v = ©(this).T::v; + r = *move(ref_v); + _ = move(this); + return move(r); + } + +} + +//# run +module 0x42.m { +import 0x42.Tester; + +entry foo() { + let t: Tester.T; + let old_ref: &mut Tester.T; + let ref_t: &mut Tester.T; + let v_from_ref: u64; + let tt: &mut Tester.T; + let v_from_t: u64; + let no: u64; +label b0: + t = Tester.new(0); + old_ref = &mut t; + ref_t = &mut t; + // cannot call replace, old_ref owns t + // this might be relaxed later + Tester.replace(copy(ref_t)); + v_from_ref = Tester.value(move(ref_t)); + tt = &mut t; + v_from_t = Tester.value(move(tt)); + assert(copy(v_from_ref) == 1, 42); + assert(copy(v_from_t) == 1, 42); + no = Tester.value(move(old_ref)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_value.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_value.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_value.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_value.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_value.mvir new file mode 100644 index 000000000..bfef433d9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/assign_local_value.mvir @@ -0,0 +1,17 @@ +//# run +module 0x42.m { + +entry foo() { + let v: u64; + let ref_v: &mut u64; +label b0: + v = 5; + ref_v = &mut v; + assert(*copy(ref_v) == 5, 42); + *copy(ref_v) = 42; // safe to modify ref + assert(*move(ref_v) == 42, 42); + assert(copy(v) == 42, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_copy_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_copy_ok.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_copy_ok.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_copy_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_copy_ok.mvir new file mode 100644 index 000000000..e163af0e2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_copy_ok.mvir @@ -0,0 +1,36 @@ +//# publish + +module 0x1.B { + struct T has drop {g: u64} + + public new(g: u64): Self.T { + label b0: + return T{g: move(g)}; + } + + public t(this: &Self.T) { + let g: &u64; + let y: u64; + label b0: + g = ©(this).T::g; + // can read g even with the live parent reference + y = *move(g); + _ = move(this); + return; + } +} + +//# run +module 0x42.m { +import 0x1.B; + +entry foo() { + let x: B.T; + let y: &B.T; +label b0: + x = B.new(5); + y = &x; + B.t(move(y)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_field_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_field_ok.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_field_ok.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_field_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_field_ok.mvir new file mode 100644 index 000000000..8e14ad6a7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_field_ok.mvir @@ -0,0 +1,40 @@ +//# publish +module 0x1.A { + + struct T has drop {v: u64} + struct K has drop {f: Self.T} + + public new_T(v: u64) : Self.T { + label b0: + return T{v: move(v)}; + } + + public new_K(f: Self.T) : Self.K { + label b0: + return K{f: move(f)}; + } + + public value(this: &Self.K) : u64 { + let k: &u64; + label b0: + k = &(&move(this).K::f).T::v; // valid field borrow + return *move(k); + } +} + +//# run +module 0x42.m { +import 0x1.A; + +entry foo() { + let x: A.T; + let y: A.K; + let z: u64; +label b0: + x = A.new_T(2); + y = A.new_K(move(x)); + z = A.value(&y); + assert(move(z) == 2, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_if.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_if.exp new file mode 100644 index 000000000..bf8c5677e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_if.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-18: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_UNAVAILABLE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_if.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_if.mvir new file mode 100644 index 000000000..932b30c38 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_if.mvir @@ -0,0 +1,18 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let ref: &u64; +label b0: + x = 5; + jump_if_false (true) b2; +label b1: + ref = &x; +label b2: + // cannot use reference as it was not assigned in all control flow paths + assert(*move(ref) == 5, 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_in_loop.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_in_loop.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_in_loop.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_in_loop.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_in_loop.mvir new file mode 100644 index 000000000..ddc4f15af --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_in_loop.mvir @@ -0,0 +1,12 @@ + +//# publish +module 0x42.m { +foo() { + let x: u64; + let r: &u64; + label l0: + x = 0; + r = &x; + jump l0; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.exp new file mode 100644 index 000000000..cefe0fe3a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-16: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: RET_BORROWED_MUTABLE_REFERENCE_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.mvir new file mode 100644 index 000000000..b70119272 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_return_mutable_borrow_bad.mvir @@ -0,0 +1,16 @@ +//# publish +module 0x1.M { + struct X { f: Self.Y } + struct Y { g: u64, h: u64 } + + t1(ref_x: &mut Self.X): &mut Self.Y * &u64 { + let ref_x_f: &mut Self.Y; + let ref_x_f_g: &u64; + label b0: + ref_x_f = &mut move(ref_x).X::f; + ref_x_f_g = & copy(ref_x_f).Y::g; + + // mutable return value overlaps with other return value + return (move(ref_x_f), move(ref_x_f_g)); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.mvir new file mode 100644 index 000000000..7d8876108 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/borrow_x_in_if_y_in_else.mvir @@ -0,0 +1,23 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; + let ref: &u64; +label b0: + x = 1; + y = 2; + jump_if (true) b2; +label b1: + ref = &y; + jump b3; +label b2: + ref = &x; + jump b3; +label b3: + assert(*move(ref) == 1, 42); // valid to read reference even though different locals borrowed + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed.mvir new file mode 100644 index 000000000..2bb87d49f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed.mvir @@ -0,0 +1,15 @@ +//# publish +module 0x1.Tester { + t() { + let x: u64; + let r1: &u64; + let r2: &u64; + label b0: + x = 0; + r1 = &x; + r2 = &x; + // valid to copy even though x is imm borrowed + _ = copy(x) + copy(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field.mvir new file mode 100644 index 000000000..396ce19de --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field.mvir @@ -0,0 +1,21 @@ +//# publish +module 0x1.Tester { + struct T has copy { f: u64 } + + t() { + let x: Self.T; + let r1: &u64; + let r2: &u64; + let f: u64; + label b0: + x = T { f: 0 }; + r1 = &(&x).T::f; + r2 = &(&x).T::f; + // copy is valid here even though immutably borrowed + T { f: f } = copy(x); + _ = move(r1); + _ = move(r2); + T { f: f } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.exp new file mode 100644 index 000000000..58c50b9f5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: COPYLOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.mvir new file mode 100644 index 000000000..6eb28582a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_field_invalid.mvir @@ -0,0 +1,17 @@ +//# publish +module 0x1.Tester { + struct T has copy { f: u64 } + + t() { + let x: Self.T; + let r1: &mut u64; + let f: u64; + label b0: + x = T { f: 0 }; + r1 = &mut (&mut x).T::f; + // cannot copy x, data is partially owned by r1. violates ref trans + T { f: f } = copy(x); + T { f: f } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.mvir new file mode 100644 index 000000000..6bc631f06 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.Tester { + t() { + let x: u64; + let y: u64; + let r1: &u64; + let r2: &u64; + label b0: + x = 0; + y = 0; + r1 = Self.foo(&x, &y); + r2 = Self.foo(&x, &y); + // valid to copy locals even though imm borrowed + _ = copy(x) + copy(x); + _ = copy(y) + copy(y); + return; + } + + foo(r: &u64, r2: &u64): &u64 { + label b0: + return move(r2); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.exp new file mode 100644 index 000000000..a666808ce --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: COPYLOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.mvir new file mode 100644 index 000000000..560f4717f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_indirect_invalid.mvir @@ -0,0 +1,20 @@ +//# publish +module 0x1.Tester { + t() { + let x: u64; + let y: u64; + let r1: &mut u64; + label b0: + x = 0; + y = 0; + r1 = Self.foo(&mut x, &mut y); + // cannot copy, data is "owned" by r1. Would violate ref trans + _ = copy(x); + return; + } + + foo(r: &mut u64, r2: &mut u64): &mut u64 { + label b0: + return move(r2); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.exp new file mode 100644 index 000000000..e10bfcc93 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: COPYLOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.mvir new file mode 100644 index 000000000..6bfda4a15 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/copy_loc_borrowed_invalid.mvir @@ -0,0 +1,13 @@ +//# publish +module 0x1.Tester { + t() { + let x: u64; + let r1: &mut u64; + label b0: + x = 0; + r1 = &mut x; + // cannot copy, data is "owned" by r1. Violates ref trans + _ = copy(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_borrow_field_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_borrow_field_ok.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_borrow_field_ok.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_borrow_field_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_borrow_field_ok.mvir new file mode 100644 index 000000000..7fe6aade8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_borrow_field_ok.mvir @@ -0,0 +1,32 @@ +//# publish +module 0x1.M { + struct T has drop {f: u64} + + public new(g: u64): Self.T { + label b0: + return T{f: move(g)}; + } + + public t(this: &Self.T) { + let y: u64; + label b0: + y = *&move(this).T::f; // valid deref/read + assert(copy(y) == 2, 42); + return; + } +} + +//# run +module 0x42.m { +import 0x1.M; + +entry foo() { + let x: M.T; + let x_ref: &M.T; +label b0: + x = M.new(2); + x_ref = &x; + M.t(move(x_ref)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_copy_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_copy_bad.exp new file mode 100644 index 000000000..ea6e41089 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_copy_bad.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 12)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_copy_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_copy_bad.mvir new file mode 100644 index 000000000..67ef4a292 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_copy_bad.mvir @@ -0,0 +1,17 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let x_ref: &mut u64; + let dead: u64; +label b0: + x = 5; + x_ref = &mut x; + assert(*copy(x_ref) == 5, 42); + dead = move(x); // cannot move x, still borrowed + *move(x_ref) = 42; + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_bad.exp new file mode 100644 index 000000000..de038a27c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_bad.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-18: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_bad.mvir new file mode 100644 index 000000000..7b3c20a9e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_bad.mvir @@ -0,0 +1,18 @@ +//# publish +module 0x1.M { + struct T {v : u64} + + public new(v: u64): Self.T { + label b0: + return T{v: move(v)}; + } + + public compare(t1: &mut Self.T, t2: &mut Self.T) : bool { + let b: bool; + let x_ref: &mut u64; + label b0: + x_ref = &mut copy(t1).T::v; + b = move(t1) == move(t2); // cannot read from t1 as it is borrowed by x_ref + return move(b); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_good.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_good.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_good.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_good.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_good.mvir new file mode 100644 index 000000000..c2b8c1b8c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/deref_eq_good.mvir @@ -0,0 +1,25 @@ +//# publish +module 0x1.M { + struct T {v : u64} + + public new(v: u64): Self.T { + label b0: + return T{v: move(v)}; + } + + // valid == + public compare1 (t1: &mut Self.T, t2: &mut Self.T) : bool { + label b0: + return move(t1) == move(t2); + } + + public compare2 (t1: &mut Self.T, t2: &mut Self.T) : bool { + let b: bool; + let x_ref: &u64; + label b0: + x_ref = ©(t1).T::v; + b = move(t1) == move(t2); + _ = move(x_ref); + return move(b); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_bad.exp new file mode 100644 index 000000000..7c78f043b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_bad.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} + +task 1 'publish'. lines 15-27: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester2'. Got VMError: { + major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} + +task 2 'publish'. lines 29-41: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester3'. Got VMError: { + major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester3, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} + +task 3 'publish'. lines 43-55: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester4'. Got VMError: { + major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester4, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_bad.mvir new file mode 100644 index 000000000..583799c68 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_bad.mvir @@ -0,0 +1,55 @@ +//# publish +module 0x1.Tester { + eqtest1() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + // invalid read of mutable ref, does not currently own its data + _ = copy(r) == copy(r); + return; + } +} + +//# publish +module 0x1.Tester2 { + eqtest2() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + // invalid read of mutable ref, does not currently own its data + _ = copy(r) == move(r); + return; + } +} + +//# publish +module 0x1.Tester3 { + neqtest1() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + // invalid read of mutable ref, does not currently own its data + _ = copy(r) != copy(r); + return; + } +} + +//# publish +module 0x1.Tester4 { + neqtest2() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + // invalid read of mutable ref, does not currently own its data + _ = copy(r) != move(r); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_ok.mvir new file mode 100644 index 000000000..ce68a74b0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/eq_ok.mvir @@ -0,0 +1,44 @@ +//# publish + +// testing valid usages of == and != over references +module 0x1.Tester { + eqtest1() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + _ = freeze(copy(r)) == freeze(copy(r)); + return; + } + + eqtest2() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + _ = freeze(copy(r)) == freeze(move(r)); + return; + } + + neqtest1() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + _ = freeze(copy(r)) != freeze(copy(r)); + return; + } + + neqtest2() { + let x: u64; + let r: &mut u64; + label b0: + x = 0; + r = &mut x; + _ = freeze(copy(r)) != freeze(move(r)); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_1.exp new file mode 100644 index 000000000..782b69655 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_1.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 15)], +} + +task 1 'publish'. lines 30-57: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, + sub_status: None, + location: 0x1::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 15)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_1.mvir new file mode 100644 index 000000000..72e28070b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_1.mvir @@ -0,0 +1,57 @@ +//# publish +module 0x1.M { + struct X has drop { f: Self.Y } + struct Y has drop { g: u64, h: u64 } + + t1() { + let x: Self.X; + let ref_x: &mut Self.X; + let ref_x_f: &mut Self.Y; + let ref_x_f_g: &mut u64; + let ref_x_f_h: &mut u64; + label b0: + x = X { f: Y { g: 0, h: 0 } }; + + ref_x = &mut x; + ref_x_f = &mut move(ref_x).X::f; + ref_x_f_g = &mut copy(ref_x_f).Y::g; + + // Error: the argument for parameter b is borrowed + Self.foo(move(ref_x_f_g), move(ref_x_f)); + return; + } + + foo(a: &mut u64, b: &mut Self.Y) { + label b0: + return; + } +} + +//# publish +module 0x1.M2 { + struct X has drop { f: Self.Y } + struct Y has drop { g: u64, h: u64 } + t2() { + let x: Self.X; + let ref_x: &mut Self.X; + let ref_x_f: &mut Self.Y; + let ref_x_f_g: &mut u64; + let ref_x_f_h: &mut u64; + label b0: + x = X { f: Y { g: 0, h: 0 } }; + + ref_x = &mut x; + ref_x_f = &mut move(ref_x).X::f; + ref_x_f_g = &mut copy(ref_x_f).Y::g; + + // Error: the argument for parameter a is borrowed + Self.bar(move(ref_x_f), move(ref_x_f_g)); + return; + } + + + bar(a: &mut Self.Y, b: &mut u64) { + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.exp new file mode 100644 index 000000000..92041c10d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-31: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 13)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.mvir new file mode 100644 index 000000000..3235257cd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_invalid_2.mvir @@ -0,0 +1,31 @@ +//# publish +module 0x1.M { + struct S { g: u64 } + + t1(root: &mut Self.S, cond: bool) { + let x1: u64; + let x2: u64; + let eps: &u64; + let g_mut: &mut u64; + let g_imm: &u64; + label b0: + x1 = 0; + x2 = 1; + jump_if (move(cond)) b2; + label b1: + eps = &x1; + jump b3; + label b2: + eps = Self.bar(copy(root)); + label b3: + // Error: root has weak empty borrow and hence a field cannot be borrowed mutably + g_mut = &mut move(root).S::g; + g_imm = freeze(move(g_mut)); + return; + } + + bar(a: &mut Self.S): &u64 { + label b0: + return &move(a).S::g; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_1.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_1.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_1.mvir new file mode 100644 index 000000000..eae2628d5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_1.mvir @@ -0,0 +1,35 @@ +//# publish +module 0x1.M { + struct X has drop { f: Self.Y } + struct Y has drop { g: u64, h: u64 } + + // tests deep borrows + releases + t1() { + let x: Self.X; + let ref_x: &mut Self.X; + let ref_x_f: &mut Self.Y; + let ref_x_f_g: &mut u64; + let ref_x_f_h: &mut u64; + label b0: + x = X { f: Y { g: 0, h: 0 } }; + + ref_x = &mut x; + ref_x_f = &mut move(ref_x).X::f; + ref_x_f_g = &mut move(ref_x_f).Y::g; + + ref_x = &mut x; + ref_x_f = &mut move(ref_x).X::f; + ref_x_f_h = &mut move(ref_x_f).Y::h; + + *copy(ref_x_f_g) = *copy(ref_x_f_h); + *copy(ref_x_f_h) = *copy(ref_x_f_g); + + Self.foo(move(ref_x_f_g), move(ref_x_f_h)); + return; + } + + foo(a: &mut u64, b: &mut u64) { + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_2.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_2.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_2.mvir new file mode 100644 index 000000000..d72bba680 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/factor_valid_2.mvir @@ -0,0 +1,74 @@ +//# publish +module 0x1.M { + struct S { g: u64 } + + t1(root: &mut Self.S, cond: bool) { + let x1: u64; + let x2: u64; + let eps: &u64; + let g: &u64; + label b0: + x1 = 0; + x2 = 1; + jump_if (move(cond)) b2; + label b1: + eps = &x1; + jump b3; + label b2: + eps = Self.bar(copy(root)); + jump b3; + label b3: + g = &move(root).S::g; // valid to extend even though imm borrowed in one branch + return; + } + + t2() { + let x1: u64; + let x2: u64; + let eps: &u64; + label b0: + x1 = 0; + x2 = 1; + eps = Self.foo(&x1, &x2); + Self.baz(&x1, move(eps)); // valid to call even though imm borrows overlap + return; + } + + t3() { + let x1: u64; + let x2: u64; + let eps: &u64; + label b0: + x1 = 0; + x2 = 1; + eps = Self.foo(&x1, &x2); + Self.baz(freeze(&mut x1), move(eps)); // valid to call even though imm borrows overlap + return; + } + + foo(a: &u64, b: &u64): &u64 { + let ret: &u64; + label b0: + jump_if (*copy(a) > *copy(b)) b2; + label b1: + ret = move(b); + _ = move(a); + jump b3; + label b2: + ret = move(a); + _ = move(b); + jump b3; + label b3: + return move(ret); // valid even though different references borrowed + } + + bar(a: &mut Self.S): &u64 { + label b0: + return &move(a).S::g; + } + + baz(a: &u64, b: &u64) { + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc.mvir new file mode 100644 index 000000000..ba1630fa4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc.mvir @@ -0,0 +1,47 @@ +//# publish +module 0x1.Tester { + import 0x1.signer; + + struct Data has key { v1: u64, v2: u64 } + struct Box has key { f: u64 } + + // the key struct is here to just give a feeling why the computation might not be reorderable + bump_and_pick(data: &mut Self.Data, b1: &mut Self.Box, b2: &mut Self.Box): &u64 { + label b0: + *&mut copy(b1).Box::f = *©(data).Data::v1; + *&mut copy(b2).Box::f = *&move(data).Data::v2; + jump_if (*©(b1).Box::f >= *©(b2).Box::f) b2; + label b1: + _ = move(b1); + return &move(b2).Box::f; + label b2: + _ = move(b2); + return &move(b1).Box::f; + } + + larger_field(data: &mut Self.Data, b1: Self.Box, b2: Self.Box, drop: address, result: &mut u64) { + let returned_ref: &u64; + let dump: u64; + label b0: + assert(*&(&b1).Box::f == 0, 42); + assert(*&(&b2).Box::f == 0, 42); + + returned_ref = Self.bump_and_pick(move(data), &mut b1, &mut b2); + + // it is valid to immutably borrow the local + // even though a mut borrow + freeze would be invalid + assert(*&(&b1).Box::f != 0, 42); + assert(*&(&b2).Box::f != 0, 42); + assert( + // (*copy(returned_ref) == *&(&b1).Box::f) ^ (*copy(returned_ref) == *&(&b2).Box::f), + (*copy(returned_ref) == *&(&b1).Box::f) != (*copy(returned_ref) == *&(&b2).Box::f), + 42 + ); + + *move(result) = *move(returned_ref); + Box { dump } = move(b1); + Box { dump } = move(b2); + + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.mvir new file mode 100644 index 000000000..aca8724e3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial.mvir @@ -0,0 +1,27 @@ +//# publish +module 0x1.Tester { + struct X has key { f: u64 } + + bump_and_give(x_ref: &mut Self.X, other: &u64): &u64 { + label b0: + _ = move(other); + *(&mut copy(x_ref).X::f) = *&mut copy(x_ref).X::f + 1; + return &move(x_ref).X::f; + } + + contrived_example(result: &mut u64) { + let x: Self.X; + let other: u64; + let returned_ref: &u64; + label b0: + x = X { f: 0 }; + other = 100; + returned_ref = Self.bump_and_give(&mut x, &other); + // it is valid to immutably borrow the local + // even though a mut borrow + freeze would be invalid + assert(*copy(returned_ref) == *&(&x).X::f, 42); + *move(result) = *move(returned_ref); + X { other } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.mvir new file mode 100644 index 000000000..ece5f4a82 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_trivial_valid.mvir @@ -0,0 +1,26 @@ +//# publish +module 0x1.Tester { + struct X has key { f: u64 } + + bump_and_give(x_ref: &mut Self.X, other: &u64): &u64 { + label b0: + _ = move(other); + *(&mut copy(x_ref).X::f) = *&mut copy(x_ref).X::f + 1; + return &move(x_ref).X::f; + } + + contrived_example(result: &mut u64) { + let x: Self.X; + let other: u64; + let returned_ref: &u64; + label b0: + x = X { f: 0 }; + other = 100; + returned_ref = Self.bump_and_give(&mut x, &other); + // mut borrow the local + freeze is valid here + assert(*copy(returned_ref) == *&(freeze(&mut x)).X::f, 42); + *move(result) = *move(returned_ref); + X { other } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_valid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_valid.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_valid.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_valid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_valid.mvir new file mode 100644 index 000000000..c7bef57b0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_loc_valid.mvir @@ -0,0 +1,45 @@ +//# publish +module 0x1.Tester { + import 0x1.signer; + + struct Data has key { v1: u64, v2: u64 } + struct Box has key { f: u64 } + + // the key struct is here to just give a feeling why the computation might not be reorderable + bump_and_pick(data: &mut Self.Data, b1: &mut Self.Box, b2: &mut Self.Box): &u64 { + label b0: + *&mut copy(b1).Box::f = *©(data).Data::v1; + *&mut copy(b2).Box::f = *&move(data).Data::v2; + jump_if (*©(b1).Box::f >= *©(b2).Box::f) b2; + label b1: + _ = move(b1); + return &move(b2).Box::f; + label b2: + _ = move(b2); + return &move(b1).Box::f; + } + + larger_field(data: &mut Self.Data, b1: Self.Box, b2: Self.Box, drop: address, result: &mut u64) { + let returned_ref: &u64; + let dump: u64; + label b0: + assert(*&(&b1).Box::f == 0, 42); + assert(*&(&b2).Box::f == 0, 42); + + returned_ref = Self.bump_and_pick(move(data), &mut b1, &mut b2); + + // it is valid to immutably extend the reference + // even though a mut extension + freeze would be invalid + assert( + // (*copy(returned_ref) == *&(&b1).Box::f) ^ (*copy(returned_ref) == *&(&b2).Box::f), + (*copy(returned_ref) == *&(&mut b1).Box::f) != (*copy(returned_ref) == *&(&mut b2).Box::f), + 42 + ); + + *move(result) = *move(returned_ref); + Box { dump } = move(b1); + Box { dump } = move(b2); + + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut.mvir new file mode 100644 index 000000000..a3e85b9b6 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut.mvir @@ -0,0 +1,46 @@ +//# publish +module 0x1.Tester { + import 0x1.signer; + + struct Initializer has key { x: u64, y: u64 } + struct Point { x: u64, y: u64 } + + // the key struct is here to just give a feeling why the computation might not be reorderable + set_and_pick(init: &mut Self.Initializer, p: &mut Self.Point): &mut u64 { + label b0: + *&mut copy(p).Point::x = *©(init).Initializer::x; + *&mut copy(p).Point::y = *&move(init).Initializer::y; + jump_if (*©(p).Point::x >= *©(p).Point::y) b2; + label b1: + return &mut move(p).Point::y; + label b2: + return &mut move(p).Point::x; + } + + bump_and_give(u: &mut u64): &u64 { + label b0: + *copy(u) = *copy(u) + 1; + return freeze(move(u)); + } + + larger_field(init: &mut Self.Initializer, point_ref: &mut Self.Point): &u64 { + let field_ref: &mut u64; + let returned_ref: &u64; + label b0: + assert(*©(point_ref).Point::x == 0, 42); + assert(*©(point_ref).Point::y == 0, 42); + + field_ref = Self.set_and_pick(move(init), copy(point_ref)); + returned_ref = Self.bump_and_give(move(field_ref)); + + // it is valid to immutably extend the reference + // even though a mut extension + freeze would be invalid + assert( + (*copy(returned_ref) == *©(point_ref).Point::x) && + (*copy(returned_ref) != *&move(point_ref).Point::y), + 42 + ); + + return move(returned_ref); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp new file mode 100644 index 000000000..186848589 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-47: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 23)], +} + +task 1 'publish'. lines 49-95: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester2'. Got VMError: { + major_status: FREEZEREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester2, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 23)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.mvir new file mode 100644 index 000000000..81b7d58d0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_invalid.mvir @@ -0,0 +1,95 @@ +//# publish +module 0x1.Tester { + import 0x1.signer; + + struct Initializer has key { x: u64, y: u64 } + struct Point { x: u64, y: u64 } + + // the key struct is here to just give a feeling why the computation might not be reorderable + set_and_pick(init: &mut Self.Initializer, p: &mut Self.Point): &mut u64 { + label b0: + *&mut copy(p).Point::x = *©(init).Initializer::x; + *&mut copy(p).Point::y = *&move(init).Initializer::y; + jump_if (*©(p).Point::x >= *©(p).Point::y) b2; + label b1: + return &mut move(p).Point::y; + label b2: + return &mut move(p).Point::x; + } + + bump_and_give(u: &mut u64): &u64 { + label b0: + *copy(u) = *copy(u) + 1; + return freeze(move(u)); + } + + larger_field_1(init: &mut Self.Initializer, point_ref: &mut Self.Point): &u64 { + let field_ref: &mut u64; + let returned_ref: &u64; + let x_val: u64; + label b0: + assert(*©(point_ref).Point::x == 0, 42); + assert(*©(point_ref).Point::y == 0, 42); + + field_ref = Self.set_and_pick(move(init), copy(point_ref)); + // this borrow is invalid because of field_ref + x_val = *freeze(&mut move(point_ref).Point::x); + returned_ref = Self.bump_and_give(move(field_ref)); + + // imagine some more interesting check than this assert + assert( + *copy(returned_ref) == (move(x_val) + 1), + 42 + ); + + return move(returned_ref); + } +} + +//# publish +module 0x1.Tester2 { + import 0x1.signer; + + struct Initializer has key { x: u64, y: u64 } + struct Point { x: u64, y: u64 } + + // the key struct is here to just give a feeling why the computation might not be reorderable + set_and_pick(init: &mut Self.Initializer, p: &mut Self.Point): &mut u64 { + label b0: + *&mut copy(p).Point::x = *©(init).Initializer::x; + *&mut copy(p).Point::y = *&move(init).Initializer::y; + jump_if (*©(p).Point::x >= *©(p).Point::y) b2; + label b1: + return &mut move(p).Point::y; + label b2: + return &mut move(p).Point::x; + } + + bump_and_give(u: &mut u64): &u64 { + label b0: + *copy(u) = *copy(u) + 1; + return freeze(move(u)); + } + + larger_field_2(init: &mut Self.Initializer, point_ref: &mut Self.Point): &u64 { + let field_ref: &mut u64; + let returned_ref: &u64; + let x_val: u64; + label b0: + assert(*©(point_ref).Point::x == 0, 42); + assert(*©(point_ref).Point::y == 0, 42); + + field_ref = Self.set_and_pick(move(init), copy(point_ref)); + // this freeze is invalid because of field_ref + x_val = *(&freeze(move(point_ref)).Point::x); + returned_ref = Self.bump_and_give(move(field_ref)); + + // imagine some more interesting check than this assert + assert( + *copy(returned_ref) == (move(x_val) + 1), + 42 + ); + + return move(returned_ref); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.mvir new file mode 100644 index 000000000..562db54cf --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial.mvir @@ -0,0 +1,20 @@ +//# publish +module 0x1.Tester { + struct X { f: u64 } + + bump_and_give(x_ref: &mut Self.X): &u64 { + label b0: + *(&mut copy(x_ref).X::f) = *&mut copy(x_ref).X::f + 1; + return &move(x_ref).X::f; + } + + contrived_example(x_ref: &mut Self.X): &u64 { + let returned_ref: &u64; + label b0: + returned_ref = Self.bump_and_give(copy(x_ref)); + // it is valid to immutably extend the reference + // even though a mut extension + freeze would be invalid + assert(*copy(returned_ref) == *&move(x_ref).X::f, 42); + return move(returned_ref); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp new file mode 100644 index 000000000..fd136e2a4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-29: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Tester'. Got VMError: { + major_status: BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x1::Tester, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.mvir new file mode 100644 index 000000000..87a3bc73f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/imm_borrow_on_mut_trivial_invalid.mvir @@ -0,0 +1,29 @@ +//# publish +module 0x1.Tester { + struct X { f: u64 } + + bump_and_give(x_ref: &mut Self.X): &u64 { + label b0: + *(&mut copy(x_ref).X::f) = *&mut copy(x_ref).X::f + 1; + return &move(x_ref).X::f; + } + + contrived_example_no(x_ref: &mut Self.X): &u64 { + let returned_ref: &u64; + label b0: + returned_ref = Self.bump_and_give(copy(x_ref)); + // ERROR Cannot mutably borrow from `x_ref` it is being borrowed by `returned_ref` + assert(*copy(returned_ref) == *freeze(&mut move(x_ref).X::f) + 1, 42); + return move(returned_ref); + } + + contrived_example_valid(x_ref: &mut Self.X): &u64 { + let returned_ref: &u64; + label b0: + returned_ref = Self.bump_and_give(copy(x_ref)); + // This is still valid, but might not be in other cases. See other Imm Borrow tests + // i.e. you might hit FreezeRefExistsMutableBorrowError + assert(*copy(returned_ref) == *(&freeze(move(x_ref)).X::f) + 1, 42); + return move(returned_ref); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.mvir new file mode 100644 index 000000000..bcdae57a1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/join_borrow_unavailable_valid.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.M { + struct S { f: u64 } + + t1(root: &mut Self.S, cond: bool) { + let u: u64; + let x: &u64; + label b0: + u = 0; + jump_if (move(cond)) b2; + label b1: + _ = move(u); + x = &move(root).S::f; + jump b3; + label b2: + x = &u; + jump b3; + label b3: + // it is okay for the two branches to disagree on the state of u, even though it is + // borrowed in one branch + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/move_one_branch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/move_one_branch.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/move_one_branch.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/move_one_branch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/move_one_branch.mvir new file mode 100644 index 000000000..7d4250a49 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/move_one_branch.mvir @@ -0,0 +1,37 @@ +//# publish +module 0x1.M { + t0(cond: bool) { + let x: u64; + let x_ref: &mut u64; + label b0: + x = 0; + x_ref = &mut x; + jump_if_false (move(cond)) b2; + label b1: + *move(x_ref) = 1; + label b2: + // safe to assign, as x is no longer borrowed + // even though the reference was only moved in one branch + x = 1; + return; + } + + t1(cond: bool) { + let x: u64; + let x_ref: &mut u64; + label b0: + x = 0; + x_ref = &mut x; + jump_if (move(cond)) b2; + label b1: + jump b3; + label b2: + *move(x_ref) = 1; + jump b3; + label b3: + // safe to assign, as x is no longer borrowed + // even though the reference was only moved in one branch + x = 1; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_invalid.exp new file mode 100644 index 000000000..80a12b091 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_invalid.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: WRITEREF_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 12)], +} + +task 1 'publish'. lines 21-44: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: CALL_BORROWED_MUTABLE_REFERENCE_ERROR, + sub_status: None, + location: 0x1::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 12)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_invalid.mvir new file mode 100644 index 000000000..3fb3163c5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_invalid.mvir @@ -0,0 +1,44 @@ +//# publish +module 0x1.M { + struct S { f: u64, g: u64, h: u64 } + + + t1(root: &mut Self.S, cond: bool) { + let x: &mut u64; + label b0: + jump_if (move(cond)) b2; + label b1: + x = &mut copy(root).S::g; + jump b3; + label b2: + x = &mut copy(root).S::f; + label b3: + *(&mut copy(root).S::f) = 1; // INVALID x is still borrowing f + return; + } +} + +//# publish +module 0x1.M2 { + + struct S { f: u64, g: u64, h: u64 } + + t2(root: &mut Self.S, cond: bool) { + let x: &mut u64; + label b0: + jump_if (move(cond)) b2; + label b1: + x = &mut copy(root).S::g; + jump b3; + label b2: + x = &mut copy(root).S::f; + label b3: + Self.foo(move(x), &mut copy(root).S::f); // INVALID x and &mut root.f overlap + return; + } + + foo(x: &mut u64, y: &mut u64) { + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice.mvir new file mode 100644 index 000000000..15848f596 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice.mvir @@ -0,0 +1,17 @@ +//# publish +module 0x1.M { + t1() { + let a: u64; + let r1: &mut u64; + let r2: &mut u64; + label b0: + a = 0; + r1 = &mut a; + r2 = &mut a; + // r1 owns the data, so it can be mutated, then r2 can mutate + // this might be relaxed later so either can be written to in either order + *move(r1) = 1; + *move(r2) = 2; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.exp new file mode 100644 index 000000000..8b2edcf88 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: WRITEREF_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.mvir new file mode 100644 index 000000000..ef6588689 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutable_borrow_local_twice_invalid.mvir @@ -0,0 +1,17 @@ +//# publish +module 0x1.M { + t1() { + let a: u64; + let r1: &mut u64; + let r2: &mut u64; + label b0: + a = 0; + r1 = &mut a; + r2 = &mut a; + // cannot write to r2, r1 "owns" the data.... + // this might be improved upon later + *move(r2) = 2; + *move(r1) = 1; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_borrow_field_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_borrow_field_ok.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_borrow_field_ok.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_borrow_field_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_borrow_field_ok.mvir new file mode 100644 index 000000000..9027bdec1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_borrow_field_ok.mvir @@ -0,0 +1,38 @@ +//# publish +module 0x42.Test { + struct T has drop {v: u64} + + public new(g: u64): Self.T { + label b0: + return T{v: move(g)}; + } + + public thousand(t : &mut Self.T) { + label b0: + *(&mut move(t).T::v) = 1000; + return; + } + + public value(this: &mut Self.T): u64 { + let y: &u64; + label b0: + y = &move(this).T::v; + return *move(y); + } +} + +//# run +module 0x42.m { +import 0x42.Test; + +entry foo() { + let x: Test.T; + let x_ref: u64; +label b0: + x = Test.new(500); + Test.thousand(&mut x); + x_ref = Test.value(&mut x); // can read references through calls + assert(move(x_ref) == 1000, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder.exp new file mode 100644 index 000000000..509d5fddf --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder.mvir new file mode 100644 index 000000000..39b003f44 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x42.A { + struct Coin has store { value: u64 } + struct T { f: Self.Coin } + + public t(this: &mut Self.T, y: Self.T) { + label b0: + *move(this) = move(y); // cannot assign/mutate without drop ability + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder_2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder_2.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder_2.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder_2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder_2.mvir new file mode 100644 index 000000000..dcfe4807f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_resource_holder_2.mvir @@ -0,0 +1,51 @@ +//# publish +module 0x42.A { + struct Coin { balance: u64 } + struct A { c: Self.Coin } + + public zero(): Self.Coin { + label b0: + return Coin { balance: 0 }; + } + + public new(c: Self.Coin): Self.A { + label b0: + return A { c: move(c) }; + } + + public destroy_a(a: Self.A) { + let c: Self.Coin; + let balance: u64; + label b0: + A { c } = move(a); + Coin { balance } = move(c); + return; + } + + public mutate(a_ref: &mut Self.A) { + let ref: &mut Self.Coin; + let ref_balance: &mut u64; + label b0: + // safe to modify resources inner values (if they have drop) + ref = &mut move(a_ref).A::c; + ref_balance = &mut move(ref).Coin::balance; + *move(ref_balance) = 100; + return; + } +} + +//# run +module 0x42.m { +import 0x42.A; + +entry foo() { + let zero_resource: A.Coin; + let s: A.A; +label b0: + zero_resource = A.zero(); + s = A.new(move(zero_resource)); + A.mutate(&mut s); + A.destroy_a(move(s)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.mvir new file mode 100644 index 000000000..89bb9cd2d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc.mvir @@ -0,0 +1,12 @@ +//# publish +module 0x1.M { + t1() { + let x: u64; + let y: &u64; + label b0: + x = 0; + y = &x; + y = &x; // it is okay to write to a local holding a reference, even if immutable + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.exp new file mode 100644 index 000000000..f7f6be1fd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.mvir new file mode 100644 index 000000000..9ee3d24b9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_invalid.mvir @@ -0,0 +1,13 @@ +//# publish +module 0x1.M { + t1() { + let x: u64; + let y: &u64; + label b0: + x = 0; + y = &x; + x = 0; // cannot write to x, still borrowed + return; + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.exp new file mode 100644 index 000000000..06d18baed --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 7)], +} + +task 1 'publish'. lines 19-35: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::N'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x1::N, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 10)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.mvir new file mode 100644 index 000000000..8a4eb6849 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/mutate_with_borrowed_loc_struct_invalid.mvir @@ -0,0 +1,35 @@ +//# publish +module 0x1.M { + struct X { b: bool } + struct S { z: u64 } + t1() { + let x: Self.X; + let y: &Self.X; + let b: bool; + label b0: + x = X { b: true }; + y = &x; + x = X { b: true }; // cannot write to x, still borrowed + _ = move(y); + X { b } = move(x); + return; + } +} + +//# publish +module 0x1.N { + struct X { b: bool } + struct S { z: u64 } + t2() { + let s: Self.S; + let y: &Self.S; + let z: &u64; + label b0: + s = S { z: 2 }; + y = &s; + z = &move(y).S::z; + s = S { z: 7 }; // cannot write to z, still borrowed + return; + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/nested_mutate.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/nested_mutate.exp new file mode 100644 index 000000000..fc5a4436b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/nested_mutate.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/nested_mutate.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/nested_mutate.mvir new file mode 100644 index 000000000..e1a98e8ef --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/nested_mutate.mvir @@ -0,0 +1,58 @@ +//# publish +module 0x42.B { + struct T has drop {g: u64} + + public new(g: u64): Self.T { + label b0: + return T{g: move(g)}; + } + + public t(this: &mut Self.T) { + let g: &mut u64; + label b0: + g = &mut copy(this).T::g; + *copy(g) = 2; + assert(*move(g) == 2, 42); + _ = move(this); + return; + } +} + +//# publish +module 0x42.A { + import 0x42.B; + struct T has drop {f: B.T} + + public new(f: B.T): Self.T { + label b0: + return T{f: move(f)}; + } + + public t(this: &mut Self.T) { + let f: &mut B.T; + label b0: + f = &mut copy(this).T::f; + // safe to modify reference through nested calls + B.t(move(f)); + _ = move(this); + return; + } +} + +//# run +module 0x42.m { +import 0x42.A; +import 0x42.B; + +entry foo() { + let b: B.T; + let x: A.T; + let x_ref: &mut A.T; +label b0: + b = B.new(0); + x = A.new(move(b)); + x_ref = &mut x; + A.t(move(x_ref)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/no_borrow_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/no_borrow_ref.exp new file mode 100644 index 000000000..a5a6aa21c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/no_borrow_ref.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: BORROWLOC_REFERENCE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/no_borrow_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/no_borrow_ref.mvir new file mode 100644 index 000000000..3a11e1067 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/no_borrow_ref.mvir @@ -0,0 +1,14 @@ +//# run +module 0x42.m { + +entry foo() { + let v: u64; + let ref_v: &u64; +label b0: + v = 5; + ref_v = &v; + _ = &ref_v; // cannot borrow a reference + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_field_after_assign_local.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_field_after_assign_local.exp new file mode 100644 index 000000000..bac0e5bb9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_field_after_assign_local.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { + major_status: WRITEREF_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::Tester, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_field_after_assign_local.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_field_after_assign_local.mvir new file mode 100644 index 000000000..f3b7d3d17 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_field_after_assign_local.mvir @@ -0,0 +1,21 @@ +//# publish +module 0x42.Tester { + struct T has drop {v: u64} + + public new(v: u64): Self.T { + label b0: + return T{v: move(v)}; + } + + public replace(t: &mut Self.T) { + let t_v: &mut u64; + let new_t: Self.T; + label b0: + t_v = &mut copy(t).T::v; + new_t = Self.new(1); + *move(t) = move(new_t); // cannot write to t, still borrowed + + assert(*move(t_v) == 1, 42); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_assign.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_assign.exp new file mode 100644 index 000000000..5a7bb2217 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_assign.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: READREF_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 18)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_assign.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_assign.mvir new file mode 100644 index 000000000..da9638557 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_assign.mvir @@ -0,0 +1,20 @@ +//# run +module 0x42.m { + +entry foo() { + let v: u64; + let read_ref: &mut u64; + let assign_ref: &mut u64; + let no: u64; +label b0: + v = 5; + read_ref = &mut v; + assign_ref = copy(read_ref); + *copy(assign_ref) = 0; + assert(*copy(assign_ref) == 0, 42); + no = *move(read_ref); // valid to read reference after assiging a copy! + _ = move(assign_ref); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_move.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_move.exp new file mode 100644 index 000000000..a75f7d19c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_move.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-15: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_move.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_move.mvir new file mode 100644 index 000000000..5b637ac4a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/read_local_ref_after_move.mvir @@ -0,0 +1,15 @@ +//# run +module 0x42.m { + +entry foo() { + let v: u64; + let ref_v: &mut u64; + let dead: u64; +label b0: + v = 5; + ref_v = &mut v; + dead = move(v); // cannot move v, it is still borrowed + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/ref_moved_one_branch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/ref_moved_one_branch.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/ref_moved_one_branch.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/ref_moved_one_branch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/ref_moved_one_branch.mvir new file mode 100644 index 000000000..98a385b96 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/ref_moved_one_branch.mvir @@ -0,0 +1,21 @@ +//# publish +module 0x1.A { + struct S {value: u64} + + public t(changed: bool, s: &mut Self.S) { + label b0: + // valid to move a reference in one branch and not the other + jump_if (move(changed)) b2; + label b1: + return; + label b2: + Self.foo(&mut move(s).S::value); + return; + } + + foo(x: &mut u64) { + label b0: + *copy(x) = *copy(x) + 1; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/release_cycle.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/release_cycle.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/release_cycle.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/release_cycle.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/release_cycle.mvir new file mode 100644 index 000000000..1f94bb952 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/release_cycle.mvir @@ -0,0 +1,25 @@ +//# publish +module 0x1.M { + t0(cond: bool) { + let v: u64; + let x: &u64; + let y: &u64; + label b0: + v = 0; + jump_if (move(cond)) b2; + label b1: + y = &v; + x = copy(y); + jump b3; + label b2: + x = &v; + y = copy(x); + jump b3; + label b3: + // the relationship between the references can be viewed as cyclic + // reference_safety must be careful when releasing + _ = move(x); + _ = move(y); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_local_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_local_ref.exp new file mode 100644 index 000000000..e9f47104d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_local_ref.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Tester'. Got VMError: { + major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, + sub_status: None, + location: 0x42::Tester, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_local_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_local_ref.mvir new file mode 100644 index 000000000..dc5d66c95 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_local_ref.mvir @@ -0,0 +1,12 @@ +//# publish +module 0x42.Tester { + public no(): &u64 { + let x: u64; + let x_ref: &u64; + label b0: + x = 5; + x_ref = &x; + return move(x_ref); // cannot return references not rooted in params + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc.mvir new file mode 100644 index 000000000..5c53dfc58 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc.mvir @@ -0,0 +1,27 @@ +//# publish +module 0x1.M { + struct X has drop { y: Self.Y } + struct Y has drop { u: u64 } + + t1() { + let x: u64; + let y: &u64; + label b0: + x = 0; + y = &x; + return; + } + + t2() { + let s: Self.X; + let x: &Self.X; + let y: &Self.Y; + let u: &u64; + label b0: + s = X { y: Y { u: 0 } }; + x = &s; + y = ©(x).X::y; + u = ©(y).Y::u; + return; // all references are automatically released, return is safe + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.exp new file mode 100644 index 000000000..d13601768 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-15: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} + +task 1 'publish'. lines 17-30: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, + sub_status: None, + location: 0x1::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} + +task 2 'publish'. lines 32-49: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, + sub_status: None, + location: 0x1::M3, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 13)], +} + +task 3 'publish'. lines 51-68: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { + major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, + sub_status: None, + location: 0x1::M4, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 13)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.mvir new file mode 100644 index 000000000..1e45cc016 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_invalid.mvir @@ -0,0 +1,68 @@ +//# publish +module 0x1.M { + struct X has drop { y: Self.Y } + struct Y has drop { u: u64 } + + t1(): &u64 { + let x: u64; + let y: &u64; + label b0: + x = 0; + y = &x; + // invalid return, borrowing a local + return move(y); + } +} + +//# publish +module 0x1.M2 { + struct X has drop { y: Self.Y } + struct Y has drop { u: u64 } + t2(): &u64 { + let x: u64; + let y: &u64; + label b0: + x = 0; + y = &x; + // invalid return, borrowing a local + return copy(y); + } +} + +//# publish +module 0x1.M3 { + struct X has drop { y: Self.Y } + struct Y has drop { u: u64 } + t3(): &u64 { + let s: Self.X; + let x: &Self.X; + let y: &Self.Y; + let u: &u64; + label b0: + s = X { y: Y { u: 0 } }; + x = &s; + y = &move(x).X::y; + u = &move(y).Y::u; + // invalid return, borrowing a local + return move(u); + } +} + +//# publish +module 0x1.M4 { + struct X has drop { y: Self.Y } + struct Y has drop { u: u64 } + t4(): &u64 { + let s: Self.X; + let x: &Self.X; + let y: &Self.Y; + let u: &u64; + label b0: + s = X { y: Y { u: 0 } }; + x = &s; + y = ©(x).X::y; + u = ©(y).Y::u; + // invalid return, borrowing a local + return copy(u); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.exp new file mode 100644 index 000000000..28a4b4f71 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.mvir new file mode 100644 index 000000000..dfc763d96 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/return_with_borrowed_loc_resource_invalid.mvir @@ -0,0 +1,13 @@ +//# publish +module 0x1.M { + struct X { u: u64 } + + t() { + let s: Self.X; + let u: &u64; + label b0: + s = X { u: 0 }; + u = &(&s).X::u; + return; // unused resource even though it is "used" via a borrow + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/simple_mutate.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/simple_mutate.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/simple_mutate.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/simple_mutate.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/simple_mutate.mvir new file mode 100644 index 000000000..d08a5477e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/simple_mutate.mvir @@ -0,0 +1,35 @@ +//# publish +module 0x42.A { + struct T has drop {f: u64} + + public new(f: u64): Self.T { + label b0: + return T{f: move(f)}; + } + + public t(this: &mut Self.T) { + let f: &mut u64; + label b0: + f = &mut copy(this).T::f; + // mutation allowed + *copy(f) = 2; + assert(*move(f) == 2, 42); + _ = move(this); + return; + } +} + +//# run +module 0x42.m { +import 0x42.A; + +entry foo() { + let x: A.T; + let x_ref: &mut A.T; +label b0: + x = A.new(0); + x_ref = &mut x; + A.t(move(x_ref)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_ref.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_ref.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_ref.mvir new file mode 100644 index 000000000..1e42df54d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/two_mutable_ref.mvir @@ -0,0 +1,20 @@ +//# publish +module 0x42.M { + struct Foo { + a: u64, + b: u64, + } + + public create_mutable_field_addresses(addr: &mut Self.Foo) { + let a_ref: &mut u64; + let b_ref: &mut u64; + label b0: + // multiple mutable references to same ref valid + a_ref = &mut copy(addr).Foo::a; + b_ref = &mut copy(addr).Foo::b; + _ = move(a_ref); + _ = move(b_ref); + _ = move(addr); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_after_move.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_after_move.exp new file mode 100644 index 000000000..e9762e99a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_after_move.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'publish'. lines 12-37: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 10)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_after_move.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_after_move.mvir new file mode 100644 index 000000000..2f65fe21f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_after_move.mvir @@ -0,0 +1,37 @@ +//# publish +module 0x42.B { + struct T has copy, drop {g: u64} + + public new(g: u64): Self.T { + label b0: + return T { g: move(g) }; + } +} + + +//# publish +module 0x42.A { + import 0x42.B; + struct T{value: B.T} + public new(m: B.T): Self.T { + label b0: + return T{value: move(m)}; + } + + public t(this: &mut Self.T) { + let ref1: &mut B.T; + let ref2: &mut B.T; + let b2: B.T; + let x: B.T; + label b0: + ref1 = &mut move(this).T::value; + ref2 = copy(ref1); + b2 = B.new(3); + // cannot write to ref1, ref2 still borrows + *move(ref1) = move(b2); + + x = *move(ref2); + + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_prefix_after_move.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_prefix_after_move.exp new file mode 100644 index 000000000..fc5a4436b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_prefix_after_move.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_prefix_after_move.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_prefix_after_move.mvir new file mode 100644 index 000000000..3387fa072 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_prefix_after_move.mvir @@ -0,0 +1,56 @@ +//# publish +module 0x42.B { + struct T has copy, drop {g: u64} + + public new(g: u64): Self.T { + label b0: + return T{g: move(g)}; + } + + public t(this: &mut Self.T) { + let g: &mut u64; + label b0: + g = &mut move(this).T::g; + *move(g) = 3; + return; + } +} + +//# publish +module 0x42.A { + import 0x42.B; + struct T has drop {f: B.T} + + public new(f: B.T): Self.T { + label b0: + return T{f: move(f)}; + } + + public t(this: &mut Self.T) { + let ref1: &mut B.T; + let ok: B.T; + label b0: + ref1 = &mut move(this).T::f; + B.t(copy(ref1)); + ok = *move(ref1); + return; + } +} + +//# run +module 0x42.m { +import 0x42.A; +import 0x42.B; + +entry foo() { + let b: B.T; + let x: A.T; + let x_ref: &mut A.T; +label b0: + b = B.new(0); + x = A.new(move(b)); + x_ref = &mut x; + A.t(move(x_ref)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_suffix_after_move.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_suffix_after_move.exp new file mode 100644 index 000000000..4a14be9c9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_suffix_after_move.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'publish'. lines 19-41: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 12)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_suffix_after_move.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_suffix_after_move.mvir new file mode 100644 index 000000000..7f7ad2bc5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/use_suffix_after_move.mvir @@ -0,0 +1,41 @@ +//# publish +module 0x42.B { + struct T has drop {g: u64} + + public new(g: u64): Self.T { + label b0: + return T{g: move(g)}; + } + + public t(this: &Self.T): &u64 { + let g: &u64; + label b0: + g = &move(this).T::g; + return move(g); + } +} + + +//# publish +module 0x42.A { + import 0x42.B; + struct T{f: B.T} + + public new(f: B.T): Self.T { + label b0: + return T{f: move(f)}; + } + + public t(this: &mut Self.T) { + let ref1: &mut B.T; + let ref2: &u64; + let b2: B.T; + label b0: + ref1 = &mut move(this).T::f; + ref2 = B.t(freeze(copy(ref1))); + b2 = B.new(3); + // cannot modify, ref2 still borrows ref1 + *move(ref1) = move(b2); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_double_borrow.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_double_borrow.exp new file mode 100644 index 000000000..1e4eb82c2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_double_borrow.exp @@ -0,0 +1,28 @@ +processed 3 tasks + +task 0 'run'. lines 1-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 14)], +} + +task 1 'run'. lines 20-38: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: BORROWLOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 12)], +} + +task 2 'run'. lines 39-57: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 14)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_double_borrow.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_double_borrow.mvir new file mode 100644 index 000000000..5dbacd904 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_double_borrow.mvir @@ -0,0 +1,57 @@ +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let e_imm1: &u64; + let e_mut2: &mut u64; +label b0: + v = vec_pack_0(); + vec_push_back(&mut v, 0); + vec_push_back(&mut v, 1); + + e_imm1 = vec_imm_borrow(&v, 0); + e_mut2 = vec_mut_borrow(&mut v, 1); + + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let e_mut1: &mut u64; + let e_imm2: &u64; +label b0: + v = vec_pack_0(); + vec_push_back(&mut v, 0); + vec_push_back(&mut v, 1); + + e_mut1 = vec_mut_borrow(&mut v, 0); + e_imm2 = vec_imm_borrow(&v, 1); + + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let e_mut1: &mut u64; + let e_mut2: &mut u64; +label b0: + v = vec_pack_0(); + vec_push_back(&mut v, 0); + vec_push_back(&mut v, 1); + + e_mut1 = vec_mut_borrow(&mut v, 0); + e_mut2 = vec_mut_borrow(&mut v, 1); + + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.exp new file mode 100644 index 000000000..ab2723058 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'run'. lines 1-16: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 9)], +} + +task 1 'run'. lines 17-32: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: MOVELOC_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 9)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.mvir new file mode 100644 index 000000000..28c85c1e8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_move_after_borrow.mvir @@ -0,0 +1,32 @@ +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let e_imm: &u64; +label b0: + v = vec_pack_0(); + vec_push_back(&mut v, 0); + e_imm = vec_imm_borrow(&v, 0); + + _ = move(v); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let e_mut: &mut u64; +label b0: + v = vec_pack_0(); + vec_push_back(&mut v, 0); + e_mut = vec_mut_borrow(&mut v, 0); + + _ = move(v); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.exp new file mode 100644 index 000000000..c4aa07bb2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'run'. lines 1-16: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 10)], +} + +task 1 'run'. lines 17-32: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 10)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.mvir new file mode 100644 index 000000000..400bca80e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/vector_ops_pop_after_borrow.mvir @@ -0,0 +1,32 @@ +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let e_imm: &u64; +label b0: + v = vec_pack_0(); + vec_push_back(&mut v, 0); + e_imm = vec_imm_borrow(&v, 0); + + _ = vec_pop_back(&mut v); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let e_mut: &mut u64; +label b0: + v = vec_pack_0(); + vec_push_back(&mut v, 0); + e_mut = vec_mut_borrow(&mut v, 0); + + _ = vec_pop_back(&mut v); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_invalid.exp new file mode 100644 index 000000000..7eb266510 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_invalid.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: WRITEREF_EXISTS_BORROW_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 10)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_invalid.mvir new file mode 100644 index 000000000..0080afa0d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_invalid.mvir @@ -0,0 +1,17 @@ +//# publish +module 0x1.M { + struct G has drop { v: u64 } + struct S has drop { g: Self.G } + + t1(root: &mut Self.S, cond: bool) { + let v_mut: &mut u64; + let g_mut: &mut Self.G; + label b0: + v_mut = &mut (&mut copy(root).S::g).G::v; + g_mut = &mut copy(root).S::g; + + // INVALID cannot write with v_mut live + *move(g_mut) = G { v: 0 }; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid1.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid1.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid1.mvir new file mode 100644 index 000000000..f08aca005 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid1.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x1.M { + struct G has drop { v1: u64, v2: u64 } + struct S { g1: Self.G, g2: Self.G } + + t1(root: &mut Self.S, cond: bool) { + let v1_mut: &mut u64; + let v2_mut: &mut u64; + let g2_mut: &mut Self.G; + label b0: + v1_mut = &mut (&mut copy(root).S::g1).G::v1; + v2_mut = &mut (&mut copy(root).S::g1).G::v2; + + g2_mut = &mut copy(root).S::g2; + + // all writes valid as they are on different fields/subtrees + *copy(g2_mut) = G { v1: 0, v2: 0 }; + *copy(v2_mut) = 0; + *copy(v1_mut) = 1; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid2.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid2.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid2.mvir new file mode 100644 index 000000000..d5f03cce3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/reference_safety/writeref_borrow_valid2.mvir @@ -0,0 +1,37 @@ +//# publish +module 0x1.M { + struct S { f: u64, g: u64, h: u64 } + + t1(root: &mut Self.S, cond: bool) { + let x: &mut u64; + label b0: + jump_if (move(cond)) b2; + label b1: + x = &mut copy(root).S::g; + jump b3; + label b2: + x = &mut copy(root).S::f; + jump b3; + label b3: + // can write even though f and g are borrowed + *(&mut copy(root).S::h) = 0; + return; + } + + t2(root: &mut Self.S, cond: bool) { + let x: &mut u64; + label b0: + jump_if (move(cond)) b2; + label b1: + x = &mut copy(root).S::g; + jump b3; + label b2: + x = &mut copy(root).S::f; + jump b3; + label b3: + // can borrow even though f and g are borrowed + _ = &mut copy(root).S::f; + _ = &mut copy(root).S::g; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_type_parameters_in_args.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_type_parameters_in_args.exp new file mode 100644 index 000000000..b134af1ae --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_type_parameters_in_args.exp @@ -0,0 +1 @@ +processed 5 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_type_parameters_in_args.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_type_parameters_in_args.mvir new file mode 100644 index 000000000..7105f5401 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_type_parameters_in_args.mvir @@ -0,0 +1,46 @@ +//# run --type-args u64 --args 0 +module 0x1.m { +// all invalid signatures +entry foo(x: T) { +label b0: + return; +} +} + + +//# run --type-args u8 --args 1u8 +module 0x2.m { + +entry foo(x: &T) { +label b0: + return; +} + +} + +//# run --type-args u8 --args b"hello" +module 0x3.m { + +entry foo(v: vector) { +label b0: + return; +} + +} + +//# publish +module 0x42.M { + struct Box has drop { x: T } +} + + +//# run --type-args u8 --args 0u8 +module 0x4.m { +// bit of a hack but works because structs have no overhead +import 0x42.M; + +entry foo(x: M.Box>) { +label b0: + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_generic_type_arg.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_generic_type_arg.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_generic_type_arg.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_generic_type_arg.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_generic_type_arg.mvir new file mode 100644 index 000000000..39f8c3dcb --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_generic_type_arg.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.M { + struct Cup { flag: u64 } +} + +//# run --type-args 0x1::M::Cup<0x1::M::Cup> +module 0x42.m { + +entry foo() { +label b0: + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_type_parameters.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_type_parameters.exp new file mode 100644 index 000000000..be2432897 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_type_parameters.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 20-28: +Error: Function execution failed with VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_type_parameters.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_type_parameters.mvir new file mode 100644 index 000000000..df27914fc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/script_with_type_parameters.mvir @@ -0,0 +1,28 @@ +//# publish +module 0x1.Coin { + struct Coin { value: u64 } + public value(c: &Self.Coin): u64 { + label b0: + return *&move(c).Coin::value; + } + public zero(): Self.Coin { + label b0: + return Coin { value: 0 }; + } + public destroy_zero(c: Self.Coin) { + label b0: + Coin {} = move(c); + assert(() == 0, 42); + return; + } +} + +//# run --type-args u64 u8 0x1::Coin::Coin +module 0x42.m { + +entry foo() { +label b0: + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_double_signer.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_double_signer.exp new file mode 100644 index 000000000..42c6b5aa5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_double_signer.exp @@ -0,0 +1,19 @@ +processed 3 tasks + +task 0 'run'. lines 1-8: +Error: Function execution failed with VMError: { + major_status: NUMBER_OF_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} + +task 1 'run'. lines 10-17: +Error: Function execution failed with VMError: { + major_status: NUMBER_OF_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_double_signer.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_double_signer.mvir new file mode 100644 index 000000000..e876f40e9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_double_signer.mvir @@ -0,0 +1,26 @@ +//# run --signers 0x1 +module 0x42.m { +// missing signer +entry foo(s: signer, s2: signer) { +label b0: + return; +} +} + +//# run --signers 0x1 --args 0 +module 0x1.m { +// missing signer +entry foo(s: signer, s2: signer, u: u64,) { +label b0: + return; +} +} + +//# run --args @0x1 0 @0x2 +module 0x2.m { +// no longer an invalid signature, after V5 +entry foo(s: signer, u: u64, s2: signer) { +label b0: + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_misplaced_signer_arg.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_misplaced_signer_arg.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_misplaced_signer_arg.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_misplaced_signer_arg.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_misplaced_signer_arg.mvir new file mode 100644 index 000000000..891a979a7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/signer_misplaced_signer_arg.mvir @@ -0,0 +1,17 @@ +//# run --args 0 @0x1 +module 0x1.m { +// no longer an invalid signature, after V5 +entry foo(u: u64, s: &signer) { +label b0: + return; +} +} + +//# run --args 0 @0x1 1 +module 0x2.m { +// no longer an invalid signature, after V5 +entry foo(u: u64, s: &signer, u2: u64) { +label b0: + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/struct_arguments.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/struct_arguments.exp new file mode 100644 index 000000000..e677b0f02 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/struct_arguments.exp @@ -0,0 +1,19 @@ +processed 3 tasks + +task 1 'run'. lines 15-22: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'run'. lines 24-24: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x42::M, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/struct_arguments.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/struct_arguments.mvir new file mode 100644 index 000000000..0e7d0b420 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/script_signature/struct_arguments.mvir @@ -0,0 +1,24 @@ +//# publish + +// struct and struct ref arguments are now allowed +// should abort indicating no verification errors occurred + +module 0x42.M { + struct S { f: u64 } + + public entry foo(s: Self.S, i: &Self.S, m: &mut Self.S) { + label l0: + abort 0; + } +} + +//# run --args 0 0 0 +module 0x42.m { +import 0x42.M; +entry foo(s: M.S, i: &M.S, m: &mut M.S) { + label l0: + abort 0; +} +} + +//# run 0x42::M::foo --args 0 0 0 diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_all_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_all_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_all_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_all_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_all_ok.mvir new file mode 100644 index 000000000..2fdae06fd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_all_ok.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_resource.exp new file mode 100644 index 000000000..b15334ba4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_resource.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_resource.mvir new file mode 100644 index 000000000..0da0a3356 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_resource.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // T does not have key + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_unrestricted.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_unrestricted.exp new file mode 100644 index 000000000..b15334ba4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_unrestricted.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_unrestricted.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_unrestricted.mvir new file mode 100644 index 000000000..56112a5f8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/all_as_unrestricted.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // T does not have copy or drop + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script.exp new file mode 100644 index 000000000..2562da2c4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script.exp @@ -0,0 +1,73 @@ +processed 9 tasks + +task 1 'run'. lines 19-26: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x1::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'run'. lines 28-35: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x2::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 3 'run'. lines 37-44: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x3::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 4 'run'. lines 46-53: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x4::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 5 'run'. lines 55-62: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x5::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 6 'run'. lines 64-71: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x6::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 7 'run'. lines 73-80: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x7::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 8 'run'. lines 82-89: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x8::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script.mvir new file mode 100644 index 000000000..9f40f1fdc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script.mvir @@ -0,0 +1,89 @@ +//# publish +module 0x1.M { + struct K has key { dummy: bool } + + struct BoxCopy has copy { f: T } + struct BoxDrop has drop { f: T } + struct BoxStore has store { f: T } + struct BoxKey has key { f: T } + + struct NeedsCopy { dummy: bool } + struct NeedsDrop { dummy: bool } + struct NeedsStore { dummy: bool } + struct NeedsKey { dummy: bool } +} + +// tests various valid constraints in script arguments +// all tests should abort, signaling they pass verification + +//# run --type-args u64 --args false +module 0x1.m { +import 0x1.M; +entry foo(x: M.NeedsCopy) { + label l0: + abort 0; +} +} + +//# run --type-args u64 --args false +module 0x2.m { +import 0x1.M; +entry foo(x: M.NeedsDrop) { + label l0: + abort 0; +} +} + +//# run --type-args u64 --args false +module 0x3.m { +import 0x1.M; +entry foo(x: M.NeedsStore) { + label l0: + abort 0; +} +} + +//# run --type-args 0x1::M::K --args false +module 0x4.m { +import 0x1.M; +entry foo(x: M.NeedsKey) { + label l0: + abort 0; +} +} + +//# run --type-args u64 --args false +module 0x5.m { +import 0x1.M; +entry foo(x: M.NeedsCopy>) { + label l0: + abort 0; +} +} + +//# run --type-args u64 --args false +module 0x6.m { +import 0x1.M; +entry foo(x: M.NeedsDrop>) { + label l0: + abort 0; +} +} + +//# run --type-args u64 --args false +module 0x7.m { +import 0x1.M; +entry foo(x: M.NeedsStore>) { + label l0: + abort 0; +} +} + +//# run --type-args u64 --args false +module 0x8.m { +import 0x1.M; +entry foo(x: M.NeedsKey>) { + label l0: + abort 0; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script_invalid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script_invalid.exp new file mode 100644 index 000000000..4b177e4f0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script_invalid.exp @@ -0,0 +1,73 @@ +processed 9 tasks + +task 1 'run'. lines 17-24: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 2 'run'. lines 26-33: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 3 'run'. lines 35-42: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 4 'run'. lines 44-51: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 5 'run'. lines 53-60: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 6 'run'. lines 62-69: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 7 'run'. lines 71-78: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 8 'run'. lines 80-87: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script_invalid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script_invalid.mvir new file mode 100644 index 000000000..6b9ff3240 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/check_constraints_script_invalid.mvir @@ -0,0 +1,87 @@ +//# publish +module 0x1.M { + struct BoxCopy has copy { f: T } + struct BoxDrop has drop { f: T } + struct BoxStore has store { f: T } + struct BoxKey has key { f: T } + + struct NeedsCopy { dummy: bool } + struct NeedsDrop { dummy: bool } + struct NeedsStore { dummy: bool } + struct NeedsKey { dummy: bool } +} + +// tests various invalid constraints in script arguments +// all tests should give a constraint violation, even without type arguments passed in to 'run' + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsCopy) { + label l0: + abort 0; +} +} + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsDrop) { + label l0: + abort 0; +} +} + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsStore) { + label l0: + abort 0; +} +} + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsKey) { + label l0: + abort 0; +} +} + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsCopy>) { + label l0: + abort 0; +} +} + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsDrop>) { + label l0: + abort 0; +} +} + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsStore>) { + label l0: + abort 0; +} +} + +//# run +module 0x42.m { +import 0x1.M; +entry foo(x: M.NeedsKey>) { + label l0: + abort 0; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp new file mode 100644 index 000000000..3182feedc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 2), (FunctionDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.mvir new file mode 100644 index 000000000..c122ee02f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_bytecode_instruction.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.M { + id(x: T) { label b0: return move(x); } + + foo() { + let x: u64; + let y: &u64; + label b0: + y = &x; + // cannot use refs in generics + Self.id<&u64>(move(y)); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_struct.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_struct.exp new file mode 100644 index 000000000..55b3a248e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_struct.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_struct.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_struct.mvir new file mode 100644 index 000000000..3c7fc5ab7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_for_struct.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // cannot use refs in generics + let s: Self.S<&u64>; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp new file mode 100644 index 000000000..d648d45c9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.exp @@ -0,0 +1,46 @@ +processed 5 tasks + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} + +task 1 'publish'. lines 15-29: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 31-43: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 45-54: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} + +task 4 'publish'. lines 56-65: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x1::M, + indices: [], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.mvir new file mode 100644 index 000000000..d2f72ed8e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_as_type_actual_in_struct_inst_for_bytecode_instruction.mvir @@ -0,0 +1,65 @@ +//# publish +module 0x1.M { + import 0x1.signer; + + struct Some has key { item: T } + + id(x: T): T { label b0: abort(0); } + foo() { + label b0: + Self.id>(); + return; + } +} + +//# publish +module 0x1.M { + struct Some { item: T } + + foo() { + let x: u64; + let y: &u64; + let v: Self.Some; + label b0: + y = &x; + // cannot use refs in generics + v = Some<&u64> { item: move(y) }; + return; + } +} + +//# publish +module 0x1.M { + struct Some { item: T } + + foo() { + let x: &u64; + let v: Self.Some; + label b0: + // cannot use refs in generics + Some<&u64> { item: x } = move(v); + return; + } +} + +//# publish +module 0x1.M { + struct S { v: T } + + // cannot use refs in generics + foo(s: Self.S<&u64>): u64 { + label b0: + return *(*(&(&s).S::v)); + } +} + +//# publish +module 0x1.M { + struct S { v: T } + + // cannot use refs in generics + foo(s: Self.S<&u64>): u64 { + label b0: + return *(*(&mut (&mut s).S::v)); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_fields.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_fields.exp new file mode 100644 index 000000000..5c57c63f5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_fields.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-5: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_fields.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_fields.mvir new file mode 100644 index 000000000..46a31af20 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_fields.mvir @@ -0,0 +1,5 @@ +//# publish +module 0x42.M { + // no refs in fields + struct Foo { x: &u64 } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_locals_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_locals_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_locals_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_locals_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_locals_ok.mvir new file mode 100644 index 000000000..9b0f08d38 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/reference_in_locals_ok.mvir @@ -0,0 +1,8 @@ +//# publish +module 0x42.M { + foo() { + let x: &u64; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_all_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_all_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_all_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_all_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_all_ok.mvir new file mode 100644 index 000000000..7a858ab11 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_all_ok.mvir @@ -0,0 +1,12 @@ +//# publish +module 0x1.M { + struct S { b: bool } + struct R { b: bool } + + foo() { + // constraints satisfied + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_unrestricted.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_unrestricted.exp new file mode 100644 index 000000000..ec7bb4cd0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_unrestricted.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_unrestricted.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_unrestricted.mvir new file mode 100644 index 000000000..43d82ddb3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/resource_as_unrestricted.mvir @@ -0,0 +1,12 @@ +//# publish +module 0x1.M { + struct S { b: bool } + struct R { b: bool } + + foo() { + // R does not have copy or drop + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_ok.mvir new file mode 100644 index 000000000..2a72281db --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_ok.mvir @@ -0,0 +1,12 @@ +//# publish +module 0x1.M { + struct R has key { b: bool} + struct S { b: bool } + + foo() { + // satisfy constraints + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_reverse_order.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_reverse_order.exp new file mode 100644 index 000000000..a6a85c403 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_reverse_order.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} + +task 1 'publish'. lines 13-24: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M2, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_reverse_order.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_reverse_order.mvir new file mode 100644 index 000000000..7095d62b4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/two_type_actuals_reverse_order.mvir @@ -0,0 +1,24 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // bool does not have key + let x: Self.S; + label b0: + return; + } +} + +//# publish +module 0x1.M2 { + struct R has key { b: bool } + struct S { b: bool } + + foo() { + // bool does not have key, R does not have copy+drop + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_all_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_all_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_all_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_all_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_all_ok.mvir new file mode 100644 index 000000000..f9cfb8203 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_all_ok.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // no constraint + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_resource.exp new file mode 100644 index 000000000..b15334ba4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_resource.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M, + indices: [(Signature, 1), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_resource.mvir new file mode 100644 index 000000000..094a43222 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/unrestricted_as_resource.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct S { b: bool } + + foo() { + // bool does not have key + let x: Self.S; + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/vector_ops_invalid_type_args.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/vector_ops_invalid_type_args.exp new file mode 100644 index 000000000..76bd17912 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/vector_ops_invalid_type_args.exp @@ -0,0 +1,28 @@ +processed 3 tasks + +task 0 'run'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionDefinition, 0)], + offsets: [], +} + +task 1 'run'. lines 11-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionDefinition, 0)], + offsets: [], +} + +task 2 'run'. lines 21-30: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::m, + indices: [(Signature, 0), (FunctionDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/vector_ops_invalid_type_args.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/vector_ops_invalid_type_args.mvir new file mode 100644 index 000000000..38f0c4972 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/signature/vector_ops_invalid_type_args.mvir @@ -0,0 +1,30 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = vec_pack_0(); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = vec_pack_0<>(); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = vec_pack_0<&u64>(); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.exp new file mode 100644 index 000000000..57ebe2fd2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.mvir new file mode 100644 index 000000000..8bc4b3bd2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_negative_stack_size.mvir @@ -0,0 +1,10 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: + // negative stack size, abort takes an arg + abort; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_no_return.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_no_return.exp new file mode 100644 index 000000000..3a16ca719 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_no_return.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-10: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x42::m, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_no_return.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_no_return.mvir new file mode 100644 index 000000000..31664945d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_no_return.mvir @@ -0,0 +1,10 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: + // no return needed + abort 0; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.exp new file mode 100644 index 000000000..de064d97b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 11-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.mvir new file mode 100644 index 000000000..55b29920c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/abort_positive_stack_size.mvir @@ -0,0 +1,21 @@ +//# publish +module 0x1.M { + + public foo(): u64 { + label b0: + return 0; + } + +} + +//# run +module 0x42.m { +import 0x1.M; + +entry foo() { +label b0: + // positive stack size invalid even with abort + M.foo(); + abort 0; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp new file mode 100644 index 000000000..9cd487b84 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.exp @@ -0,0 +1,55 @@ +processed 6 tasks + +task 0 'run'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 1 'run'. lines 11-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 2 'run'. lines 21-30: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 3 'run'. lines 31-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 4 'run'. lines 41-50: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 5 'run'. lines 51-60: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.mvir new file mode 100644 index 000000000..a6c68adf7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_negative_stack.mvir @@ -0,0 +1,60 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: + to_u8(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + to_u16(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + to_u32(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + to_u64(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + to_u128(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + to_u256(()); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp new file mode 100644 index 000000000..a11ed8c4a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.exp @@ -0,0 +1,55 @@ +processed 6 tasks + +task 0 'run'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 1 'run'. lines 12-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 2 'run'. lines 23-33: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 3 'run'. lines 34-44: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 4 'run'. lines 45-55: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 5 'run'. lines 56-66: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.mvir new file mode 100644 index 000000000..b1d50383d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/cast_positive_stack.mvir @@ -0,0 +1,66 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: + (3); + to_u8(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3); + to_u16(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3); + to_u32(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3); + to_u64(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3); + to_u128(()); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3); + to_u256(()); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.mvir new file mode 100644 index 000000000..6da510c3b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/consume_stack.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x1.M { + struct R has key { data: vector } + + is_ok_(addr: &address, data: &vector): bool { + label b0: + return true; + } + + fake(addr: address): &Self.R { label l0: abort(0); } + + public is_ok(addr: address): bool { + label b0: + // correct stack usage + (&addr); + (0x1D8); + (&Self.fake().R::data); + Self.is_ok_(); + return; + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.exp new file mode 100644 index 000000000..f99343929 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.mvir new file mode 100644 index 000000000..fe97928a8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/exp_in_if_and_else_branch.mvir @@ -0,0 +1,19 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: + jump_if (true) b2; +label b1: + // positive stack, but never reached when checking + (5); + jump b3; +label b2: + // positive stack + (4); + jump b3; +label b3: + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.exp new file mode 100644 index 000000000..c1805b156 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 11-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.mvir new file mode 100644 index 000000000..2c3ee0f46 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_1.mvir @@ -0,0 +1,21 @@ +//# publish +module 0x1.Test { + public baz(k: u64, l: u64, m: u64) : u64 { + let z: u64; + label b0: + z = move(k) + move(l) + move(m); + return move(z); + } +} + +//# run +module 0x42.m { +import 0x1.Test; + +entry foo() { +label b0: + // negative stack + Test.baz(); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.exp new file mode 100644 index 000000000..9c8598de0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 24-37: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.mvir new file mode 100644 index 000000000..af8863f0c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_call_negative_stack_err_2.mvir @@ -0,0 +1,37 @@ +//# publish +module 0x1.A { + public push_u64(): u64 { + label b0: + return 42; + } + + public push_bool(): bool { + label b0: + return true; + } + + public foo(u: u64): u64 { + label b0: + return move(u) * 2; + } + + public eat_stack(b: bool, u: u64) { + label b0: + return; + } +} + +//# run +module 0x42.m { +import 0x1.A; + +entry foo() { + let ans: u64; +label b0: + (A.push_bool(), A.push_u64()); + ans = (A.foo()); + // negative stack + (A.eat_stack()); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.exp new file mode 100644 index 000000000..eb80ec803 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 23-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.mvir new file mode 100644 index 000000000..1e41dfc79 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_pos_and_neg_stack_err.mvir @@ -0,0 +1,40 @@ +//# publish +module 0x1.A { + public parity(u: u64): u64 * bool { + label b0: + return copy(u), (move(u) % 2 == 0); + } + + public takes_bool(b: bool): u64 { + label b0: + jump_if (move(b)) b2; + label b1: + return 0; + label b2: + return 1; + } + + public eat_stack(v: u64) { + label b0: + return; + } +} + +//# run +module 0x42.m { +import 0x1.A; + +entry foo() { + let k: u64; + let ans: u64; + let e: u64; +label b0: + k = 100; + // positive stack + ans = A.takes_bool(A.parity(move(k))); + assert(move(ans) == true, 42); + // negative stack, but never reached during checking + (A.eat_stack(), A.eat_stack()); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.exp new file mode 100644 index 000000000..cd75a322e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 18-33: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.mvir new file mode 100644 index 000000000..8ee20a4f7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_1.mvir @@ -0,0 +1,33 @@ +//# publish +module 0x1.Test { + public foo(v: u64): u64 * u64 { + let one_less: u64; + let one_more: u64; + label b0: + one_less = copy(v) - 1; + one_more = move(v) + 1; + return move(one_less), move(one_more); + } + + public bar(): u64 * u64 * u64 { + label b0: + return 500, 8, 256; + } +} + +//# run +module 0x42.m { +import 0x1.Test; + +entry foo() { + let y: u64; + let x0: u64; + let x1 : u64; +label b0: + // positive stack + x0, x1 = Test.foo(Test.bar()); + assert(move(x0) == 8, 42); + assert(move(x1) == 256, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.exp new file mode 100644 index 000000000..817380ec0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 18-32: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.mvir new file mode 100644 index 000000000..d093bfe94 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/function_composition_positive_stack_err_2.mvir @@ -0,0 +1,32 @@ +//# publish +module 0x1.A { + public parity(u: u64): u64 * bool { + label b0: + return copy(u), (move(u) % 2 == 0); + } + + public takes_bool(b: bool): u64 { + label b0: + jump_if (move(b)) b2; + label b1: + return 0; + label b2: + return 1; + } +} + +//# run +module 0x42.m { +import 0x1.A; + +entry foo() { + let k: u64; + let ans: u64; +label b0: + k = 100; + // positive stack + ans = A.takes_bool(A.parity(move(k))); + assert(move(ans) == true, 42); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.exp new file mode 100644 index 000000000..2301000e5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.exp @@ -0,0 +1 @@ +processed 6 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.mvir new file mode 100644 index 000000000..0f3bcf746 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_balanced.mvir @@ -0,0 +1,90 @@ +//# publish +module 0x1.A { + two(): u8 * u8{ + label b0: + return 0u8, 255u8; + } + + pop() { + label b0: + // balance stack, equal pops and values + _, _ = Self.two(); + return; + } +} + + +//# publish +module 0x1.B { + two(): u16 * u16{ + label b0: + return 0u16, 65535u16; + } + + pop() { + label b0: + // balance stack, equal pops and values + _, _ = Self.two(); + return; + } +} + +//# publish +module 0x1.C { + two(): u32 * u32{ + label b0: + return 0u32, 4294967295u32; + } + + pop() { + label b0: + // balance stack, equal pops and values + _, _ = Self.two(); + return; + } +} + +//# publish +module 0x1.D { + two(): u64 * u64{ + label b0: + return 0u64, 18446744073709551615u64; + } + + pop() { + label b0: + // balance stack, equal pops and values + _, _ = Self.two(); + return; + } +} + +//# publish +module 0x1.E { + two(): u128 * u128{ + label b0: + return 0u128, 340282366920938463463374607431768211455u128; + } + + pop() { + label b0: + // balance stack, equal pops and values + _, _ = Self.two(); + return; + } +} + +//# publish +module 0x1.F { + two(): u256 * u256{ + label b0: + return 0u256, 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; + } + + pop() { + label b0: + // balance stack, equal pops and values + _, _ = Self.two(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp new file mode 100644 index 000000000..14f3442e1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.exp @@ -0,0 +1,55 @@ +processed 6 tasks + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 1 'publish'. lines 17-30: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 2 'publish'. lines 32-45: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 3 'publish'. lines 47-60: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 4 'publish'. lines 62-75: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 5 'publish'. lines 77-90: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.mvir new file mode 100644 index 000000000..3c79aa538 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_negative.mvir @@ -0,0 +1,90 @@ +//# publish +module 0x1.A { + three(): u8 * u8{ + label b0: + return 0u8, 255u8; + } + + pop() { + label b0: + // negative stack size, extra pop + _, _, _ = Self.three(); + return; + } +} + + +//# publish +module 0x1.A { + three(): u16 * u16{ + label b0: + return 0u16, 65535u16; + } + + pop() { + label b0: + // negative stack size, extra pop + _, _, _ = Self.three(); + return; + } +} + +//# publish +module 0x1.A { + three(): u32 * u32{ + label b0: + return 0u32, 4294967295u32; + } + + pop() { + label b0: + // negative stack size, extra pop + _, _, _ = Self.three(); + return; + } +} + +//# publish +module 0x1.A { + three(): u64 * u64{ + label b0: + return 0u64, 18446744073709551615u64; + } + + pop() { + label b0: + // negative stack size, extra pop + _, _, _ = Self.three(); + return; + } +} + +//# publish +module 0x1.A { + three(): u128 * u128{ + label b0: + return 0u128, 340282366920938463463374607431768211455u128; + } + + pop() { + label b0: + // negative stack size, extra pop + _, _, _ = Self.three(); + return; + } +} + +//# publish +module 0x1.A { + three(): u256 * u256{ + label b0: + return 0u256, 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; + } + + pop() { + label b0: + // negative stack size, extra pop + _, _, _ = Self.three(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp new file mode 100644 index 000000000..e3e8ca2c3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.exp @@ -0,0 +1,55 @@ +processed 6 tasks + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 1 'publish'. lines 17-30: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 2 'publish'. lines 32-45: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 3 'publish'. lines 47-60: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 4 'publish'. lines 62-75: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} + +task 5 'publish'. lines 77-90: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.mvir new file mode 100644 index 000000000..d852de8a7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/integer_stack_positive.mvir @@ -0,0 +1,90 @@ +//# publish +module 0x1.A { + two(): u8 * u8{ + label b0: + return 0u8, 255u8; + } + + pop() { + label b0: + // negative stack size, missing pop + _ = Self.two(); + return; + } +} + + +//# publish +module 0x1.A { + two(): u16 * u16{ + label b0: + return 0u16, 65535u16; + } + + pop() { + label b0: + // negative stack size, missing pop + _ = Self.two(); + return; + } +} + +//# publish +module 0x1.A { + two(): u32 * u32{ + label b0: + return 0u32, 4294967295u32; + } + + pop() { + label b0: + // negative stack size, missing pop + _ = Self.two(); + return; + } +} + +//# publish +module 0x1.A { + two(): u64 * u64{ + label b0: + return 0u64, 18446744073709551615u64; + } + + pop() { + label b0: + // negative stack size, missing pop + _ = Self.two(); + return; + } +} + +//# publish +module 0x1.A { + two(): u128 * u128{ + label b0: + return 0u128, 340282366920938463463374607431768211455u128; + } + + pop() { + label b0: + // negative stack size, missing pop + _ = Self.two(); + return; + } +} + +//# publish +module 0x1.A { + two(): u256 * u256{ + label b0: + return 0u256, 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; + } + + pop() { + label b0: + // negative stack size, missing pop + _ = Self.two(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp new file mode 100644 index 000000000..6ceba7ddc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.exp @@ -0,0 +1,55 @@ +processed 6 tasks + +task 0 'run'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 1 'run'. lines 11-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 2 'run'. lines 21-30: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 3 'run'. lines 31-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 4 'run'. lines 41-50: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 5 'run'. lines 51-60: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.mvir new file mode 100644 index 000000000..51a47e9e9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/load_positive_stack.mvir @@ -0,0 +1,60 @@ +//# run +module 0x42.m { + +entry foo() { +label b0: + (3u8); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3u16); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3u32); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3u64); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3u128); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + (3u256); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.exp new file mode 100644 index 000000000..f83ed3391 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.mvir new file mode 100644 index 000000000..9622ec276 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_negative_stack.mvir @@ -0,0 +1,14 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; + let z: u64; +label b0: + // negative stack + x, y, z = (1, 2); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.exp new file mode 100644 index 000000000..71b1adad5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.mvir new file mode 100644 index 000000000..b3b61ba78 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_bindings_positive_stack.mvir @@ -0,0 +1,13 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + // positive stack + x, y = (1, 2, 4); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.mvir new file mode 100644 index 000000000..4f712c143 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values.mvir @@ -0,0 +1,43 @@ +//# publish +module 0x1.Test { + struct T { b: bool } + + public new(): Self.T { + label b0: + return T { b: true }; + } + + public test(i: &u64, x: Self.T): u64 * Self.T * bool { + label b0: + return *move(i), move(x), false; + } + + public destroy(x: Self.T) { + let b: bool; + label b0: + T { b } = move(x); + return; + } +} + +//# run +module 0x42.m { +import 0x1.Test; +entry foo() { + let i: u64; + let t: Test.T; + let a: u64; + let x: Test.T; + let b: bool; +label b0: + i = 0; + t = Test.new(); + // correctly handles multiple function return values + a, x, b = Test.test(&i, move(t)); + assert(move(a) == 0, 42); + Test.destroy(move(x)); + assert(!move(b), 43); + + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.exp new file mode 100644 index 000000000..cbed82e8f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 23-45: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.mvir new file mode 100644 index 000000000..7848d2d97 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_binding.mvir @@ -0,0 +1,45 @@ +//# publish +module 0x1.Test { + struct T { b: bool } + + public new(): Self.T { + label b0: + return T { b: true }; + } + + public test(i: &u64, x: Self.T): u64 * Self.T * bool { + label b0: + return *move(i), move(x), false; + } + + public destroy(x: Self.T) { + let b: bool; + label b0: + T { b } = move(x); + return; + } +} + +//# run +module 0x42.m { +import 0x1.Test; + +entry foo() { + let i: u64; + let t: Test.T; + let a: u64; + let b: bool; + let x: Test.T; + let z: address; +label b0: + i = 0; + t = Test.new(); + // too many stores/assignments, negative stack size + a, x, b, z = Test.test(&i, move(t)); + assert(move(a) == 0, 42); + Test.destroy(move(x)); + assert(!move(b), 43); + + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp new file mode 100644 index 000000000..892b8117e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.mvir new file mode 100644 index 000000000..c87a256dd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_extra_value.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x1.Test { + struct T { b: bool } + + public new(): Self.T { + label b0: + return T { b: true }; + } + + public test(i: &u64, x: Self.T): u64 * Self.T * bool { + label b0: + // too many "return values", return wont consume them, positive stack size + return *move(i), move(x), false, 0x0; + } + + public destroy(x: Self.T) { + let b: bool; + label b0: + T { b } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.exp new file mode 100644 index 000000000..eb80ec803 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 23-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.mvir new file mode 100644 index 000000000..13b4b9222 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_binding.mvir @@ -0,0 +1,40 @@ +//# publish +module 0x1.Test { + struct T { b: bool } + + public new(): Self.T { + label b0: + return T { b: true }; + } + + public test(i: &u64, x: Self.T): u64 * Self.T * bool { + label b0: + return *move(i), move(x), false; + } + + public destroy(x: Self.T) { + let b: bool; + label b0: + T { b } = move(x); + return; + } +} + +//# run +module 0x42.m { +import 0x1.Test; +entry foo() { + let i: u64; + let t: Test.T; + let a: u64; + let x: Test.T; +label b0: + i = 0; + t = Test.new(); + a, x = Test.test(&i, move(t)); + assert(move(a) == 0, 42); + Test.destroy(move(x)); + + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp new file mode 100644 index 000000000..e7dbcda0a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.mvir new file mode 100644 index 000000000..9a361944c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/multiple_return_values_missing_value.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x1.Test { + struct T { b: bool } + + public new(): Self.T { + label b0: + return T { b: true }; + } + + public test(i: &u64, x: Self.T): u64 * Self.T * bool { + label b0: + // too few values on stack for return, negative stack size + return *move(i), move(x); + } + + public destroy(x: Self.T) { + let b: bool; + label b0: + T { b } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.mvir new file mode 100644 index 000000000..ba04f9088 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_exact.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.A { + three(): u64 * u64 * u64 { + label b0: + return 0, 1, 2; + } + + pop() { + label b0: + // correct amount of pops + _, _, _ = Self.three(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.exp new file mode 100644 index 000000000..559dd0612 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.mvir new file mode 100644 index 000000000..8dcf844a2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_negative.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.A { + three(): u64 * u64 * u64 { + label b0: + return 0, 1, 2; + } + + pop() { + label b0: + // negative stack size, extra pop + _, _, _, _ = Self.three(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.exp new file mode 100644 index 000000000..269d1dd06 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::A'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::A, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.mvir new file mode 100644 index 000000000..916930ed5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/pop_positive.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x1.A { + three(): u64 * u64 * u64 { + label b0: + return 0, 1, 2; + } + + pop() { + label b0: + // positive stack size, missing pop + _, _ = Self.three(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp new file mode 100644 index 000000000..99f3813d6 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.mvir new file mode 100644 index 000000000..99e178593 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_extra_binding.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.Test { + struct X { b: bool } + struct T { i: u64, x: Self.X } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T { i: 0, x: move(x) }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // extra binding, invalid positive stack size + T { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp new file mode 100644 index 000000000..49c6e9980 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.mvir new file mode 100644 index 000000000..424c00fdd --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/unpack_missing_binding.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.Test { + struct X { b: bool } + struct T { i: u64, x: Self.X, b: bool, y: u64 } + + public new_t(): Self.T { + let x: Self.X; + label b0: + x = X { b: true }; + return T { i: 0, x: move(x), b: false, y: 0 }; + } + + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + // unused item in unpack, invalid positive stack + T { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp new file mode 100644 index 000000000..dcf2aa351 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'run'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 1 'run'. lines 12-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 2 'run'. lines 23-35: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: POSITIVE_STACK_SIZE_AT_BLOCK_END, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 3 'run'. lines 36-48: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.mvir new file mode 100644 index 000000000..99085f299 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/stack_usage_verifier/vector_ops_pack_unpack.mvir @@ -0,0 +1,48 @@ +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + v = vec_pack_0(true); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + v = vec_pack_1(); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let x: bool; +label b0: + v = vec_pack_1(true); + x = vec_unpack_2(move(v)); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let x: bool; +label b0: + v = vec_pack_1(true); + x = vec_unpack_0(move(v)); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/module_struct_shared_name.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/module_struct_shared_name.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/module_struct_shared_name.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/module_struct_shared_name.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/module_struct_shared_name.mvir new file mode 100644 index 000000000..41fdd2b8c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/module_struct_shared_name.mvir @@ -0,0 +1,21 @@ +//# publish +module 0x42.M { + struct M has drop { b: bool } + public new(): Self.M { + label b0: + return M{ b: true }; + } +} + +//# run +module 0x42.m { + +import 0x42.M; + +entry foo() { + let x: M.M; +label b0: + x = M.new(); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.exp new file mode 100644 index 000000000..e6cc45c48 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-6: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: RECURSIVE_STRUCT_DEFINITION, + sub_status: None, + location: 0x42::M, + indices: [(StructDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.mvir new file mode 100644 index 000000000..2b65d32be --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/mutual_recursive_struct.mvir @@ -0,0 +1,6 @@ +//# publish +module 0x42.M { + // cannot have mutually recursive structs + struct A{b: Self.B} + struct B{a: Self.A} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.exp new file mode 100644 index 000000000..86c3d6552 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.exp @@ -0,0 +1,46 @@ +processed 6 tasks + +task 1 'publish'. lines 10-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M0'. Got VMError: { + major_status: RECURSIVE_STRUCT_DEFINITION, + sub_status: None, + location: 0x1::M0, + indices: [(StructDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 16-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { + major_status: RECURSIVE_STRUCT_DEFINITION, + sub_status: None, + location: 0x1::M1, + indices: [(StructDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 30-37: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: RECURSIVE_STRUCT_DEFINITION, + sub_status: None, + location: 0x1::M2, + indices: [(StructDefinition, 1)], + offsets: [], +} + +task 4 'publish'. lines 39-46: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: RECURSIVE_STRUCT_DEFINITION, + sub_status: None, + location: 0x1::M3, + indices: [(StructDefinition, 0)], + offsets: [], +} + +task 5 'publish'. lines 48-58: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: RECURSIVE_STRUCT_DEFINITION, + sub_status: None, + location: 0x1::M3, + indices: [(StructDefinition, 3)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.mvir new file mode 100644 index 000000000..5a7390373 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/recursive_struct.mvir @@ -0,0 +1,58 @@ +//# publish +module 0x1.Cup { + struct Cup { f: T } + public cup(f: T): Self.Cup { + label b0: + return Cup { f: move(f) }; + } +} + +//# publish +module 0x1.M0 { + // recursive struct + struct Foo { f: Self.Foo } +} + +//# publish +module 0x1.M1 { + import 0x1.Cup; + // recursive struct + struct Foo { f: Cup.Cup } + + // would blow up the stack + public foo(): Self.Foo { + label b0: + return Foo { f: Cup.cup(Self.foo()) }; + } + +} + +//# publish +module 0x1.M2 { + import 0x1.signer; + + struct X { y: vector } + struct Y { x: vector } + +} + +//# publish +module 0x1.M3 { + import 0x1.Cup; + + // recursive struct + struct Foo { f: Cup.Cup } + +} + +//# publish +module 0x1.M3 { + import 0x1.Cup; + + // indirect recursive struct + struct A { b: Self.B } + struct B { c: Self.C } + struct C { d: vector } + struct D { x: Cup.Cup>> } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/ref_in_struct.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/ref_in_struct.exp new file mode 100644 index 000000000..380f15444 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/ref_in_struct.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-4: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M1, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} + +task 1 'publish'. lines 6-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M2, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 11-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M3, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 16-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { + major_status: INVALID_SIGNATURE_TOKEN, + sub_status: None, + location: 0x42::M4, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/ref_in_struct.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/ref_in_struct.mvir new file mode 100644 index 000000000..94d8606e1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/struct_defs/ref_in_struct.mvir @@ -0,0 +1,19 @@ +//# publish +module 0x42.M1 { + struct S { x: &u64 } +} + +//# publish +module 0x42.M2 { + struct S { x: &mut u64 } +} + +//# publish +module 0x42.M3 { + struct S { t: &T } +} + +//# publish +module 0x42.M4 { + struct S { t: &mut T } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/tests.rs b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/tests.rs new file mode 100644 index 000000000..68a9a2fb9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/tests.rs @@ -0,0 +1,8 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pub const TEST_DIR: &str = "tests"; +use move_transactional_test_runner::vm_test_harness::run_test; + +datatest_stable::harness!(run_test, TEST_DIR, r".*\.(mvir|move)$"); diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.exp new file mode 100644 index 000000000..509d5fddf --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.mvir new file mode 100644 index 000000000..97702f867 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x42.A { + struct Coin has store { value: u64 } + struct T { f: Self.Coin } + + public t(resource1: Self.Coin, resource2: Self.Coin) { + label b0: + *&mut resource1 = move(resource2); // cannot mutate without drop ability + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.exp new file mode 100644 index 000000000..04ab2b89d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.mvir new file mode 100644 index 000000000..4f3eab0fa --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_local_resource_twice.mvir @@ -0,0 +1,13 @@ +//# publish +module 0x42.A { + struct Coin has store { value: u64 } + struct T { f: Self.Coin } + + public t(resource_ref: &mut Self.Coin, resource1: Self.Coin, resource2: Self.Coin) { + label b0: + // cannot modify without drop ability + *move(resource_ref) = move(resource1); + *move(resource_ref) = move(resource2); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type.exp new file mode 100644 index 000000000..a830d1e9b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::A'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x42::A, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type.mvir new file mode 100644 index 000000000..521ef3665 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_resource_type.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x42.A { + struct Coin has store { value: u64 } + struct T { f: Self.Coin } + + public t(this: &mut Self.T, y: Self.Coin) { + let x: &mut Self.Coin; + label b0: + x = &mut move(this).T::f; + *move(x) = move(y); // cannot assign/mutate without drop ability + return; + } +} +// check: WRITEREF_WITHOUT_DROP_ABILITY diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_wrong_type.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_wrong_type.exp new file mode 100644 index 000000000..ca80c7b64 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_wrong_type.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_wrong_type.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_wrong_type.mvir new file mode 100644 index 000000000..833493d5c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/assign_wrong_type.mvir @@ -0,0 +1,11 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; +label b0: + x = false; // invalid assignment + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/boolean_not_non_boolean.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/boolean_not_non_boolean.exp new file mode 100644 index 000000000..d33c358b3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/boolean_not_non_boolean.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: BOOLEAN_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/boolean_not_non_boolean.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/boolean_not_non_boolean.mvir new file mode 100644 index 000000000..374704b06 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/boolean_not_non_boolean.mvir @@ -0,0 +1,12 @@ +//# run +module 0x42.m { + +entry foo() { + let x: bool; +label b0: + x = !0; + return; +} + +} +// check: BOOLEAN_OP_TYPE_MISMATCH_ERROR diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.exp new file mode 100644 index 000000000..22c3e9e7d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-42: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { + major_status: READREF_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::Token, + indices: [(FunctionDefinition, 4)], + offsets: [(FunctionDefinitionIndex(4), 13)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.mvir new file mode 100644 index 000000000..191086b1e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/cant_deref_resource.mvir @@ -0,0 +1,42 @@ +//# publish +module 0x1.Token { + import 0x1.signer; + + struct T has key {v: u64} + + public new(v: u64): Self.T { + label b0: + return T{v: move(v)}; + } + + public value(this: &Self.T): u64 { + let vref: &u64; + let res: u64; + label b0: + vref = &move(this).T::v; + // T does not have copy + res = *move(vref); + return move(res); + } + + public publish(account: &signer, t: Self.T) { + label b0: + abort(0); + } + + fake(addr: address): &mut Self.T { label b0: abort(0); } + + public test(account: &signer) { + let addr: address; + let t: Self.T; + let tref: &mut Self.T; + let y: Self.T; + label b0: + addr = signer.address_of(copy(account)); + t = Self.new(0); + Self.publish(copy(account), move(t)); + tref = Self.fake(move(addr)); + y = *move(tref); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/casting_operators_types_mismatch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/casting_operators_types_mismatch.exp new file mode 100644 index 000000000..370ebe467 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/casting_operators_types_mismatch.exp @@ -0,0 +1,163 @@ +processed 18 tasks + +task 0 'run'. lines 1-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'run'. lines 11-20: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'run'. lines 21-30: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 3 'run'. lines 31-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 4 'run'. lines 41-50: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 5 'run'. lines 51-60: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 6 'run'. lines 62-71: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 7 'run'. lines 72-81: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 8 'run'. lines 82-91: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 9 'run'. lines 92-101: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 10 'run'. lines 102-111: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 11 'run'. lines 112-121: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 12 'publish'. lines 123-131: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 13 'publish'. lines 133-141: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 14 'publish'. lines 143-151: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 15 'publish'. lines 153-161: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 16 'publish'. lines 163-171: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 17 'publish'. lines 173-181: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/casting_operators_types_mismatch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/casting_operators_types_mismatch.mvir new file mode 100644 index 000000000..cfd0b7af4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/casting_operators_types_mismatch.mvir @@ -0,0 +1,181 @@ +//# run +module 0x42.m { +// tests bad casts/integer conversions +entry foo() { +label b0: + _ = to_u8(true); + return; +} +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u64(true); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u128(true); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u16(true); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u32(true); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u256(true); + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u8(0x0); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u64(0x0); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u128(0x0); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u16(0x0); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u32(0x0); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = to_u256(0x0); + return; +} + +} + +//# publish +module 0x42.M { + struct S { x: bool } + f() { + label b0: + _ = to_u8(S { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct S { x: bool } + g() { + label b0: + _ = to_u64(S { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct S { x: bool } + h() { + label b0: + _ = to_u128(S { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct S { x: bool } + f() { + label b0: + _ = to_u16(S { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct S { x: bool } + g() { + label b0: + _ = to_u32(S { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct S { x: bool } + h() { + label b0: + _ = to_u256(S { x: true }); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_non_reference.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_non_reference.exp new file mode 100644 index 000000000..125e602b1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_non_reference.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: READREF_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_non_reference.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_non_reference.mvir new file mode 100644 index 000000000..307b9e532 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_non_reference.mvir @@ -0,0 +1,13 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 0; + y = *move(x); // cannot deref a u64 + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_not_reference_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_not_reference_bad.exp new file mode 100644 index 000000000..de9a2c908 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_not_reference_bad.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: BOOLEAN_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_not_reference_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_not_reference_bad.mvir new file mode 100644 index 000000000..2a779a054 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/deref_not_reference_bad.mvir @@ -0,0 +1,13 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let y: u64; +label b0: + x = 0; + y = *!move(x); // cannot deref a bool + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/destroy_resource_holder.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/destroy_resource_holder.exp new file mode 100644 index 000000000..4649cb71e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/destroy_resource_holder.exp @@ -0,0 +1,4 @@ +processed 2 tasks + +task 1 'run'. lines 22-35: +Error: Unbound module alias Diem diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/destroy_resource_holder.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/destroy_resource_holder.mvir new file mode 100644 index 000000000..c4c8ab201 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/destroy_resource_holder.mvir @@ -0,0 +1,35 @@ +//# publish +module 0x42.A { + + struct Coin has store { value: u64 } + struct A { c: Self.Coin } + + public destroy_zero(c: Self.Coin) { + label b0: + Coin {} = move(c); + assert(() == 0, 42); + return; + } + + public destroy_a(a: Self.A) { + label b0: + A {} = move(a); + Self.destroy_zero(); + return; + } +} + +//# run +module 0x42.m { +import 0x42.A; + +entry foo() { + let zero_resource: Diem.Diem; + let s: A.A; +label b0: + zero_resource = Diem.zero(); + s = A.new(move(zero_resource)); + A.destroy_a(move(s)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_one_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_one_ref.exp new file mode 100644 index 000000000..aba1abef1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_one_ref.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-15: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_one_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_one_ref.mvir new file mode 100644 index 000000000..232453ec7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_one_ref.mvir @@ -0,0 +1,15 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let x_ref: &u64; + let no: bool; +label b0: + x = 0; + x_ref = &x; + no = 0 == move(x_ref); // == type mismatch + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.mvir new file mode 100644 index 000000000..5aa54e565 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_refs.mvir @@ -0,0 +1,27 @@ +//# publish +module 0x1.Token { + struct T has key { b: bool } + + public test() { + let t: Self.T; + let t_ref: &Self.T; + let b: bool; + label b0: + t = T{ b: true }; + t_ref = &t; + assert(copy(t_ref) == move(t_ref), 42); // == works over refs, even if resources without drop + T{ b } = move(t); + return; + } +} + +//# run +module 0x42.m { +import 0x1.Token; + +entry foo() { +label b0: + Token.test(); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.exp new file mode 100644 index 000000000..9f367810c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Token'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::Token, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.mvir new file mode 100644 index 000000000..13fa89cfc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/equality_resource_values.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.Token { + struct T has key { b: bool } + + public test() { + let no: bool; + label b0: + no = T{ b: true } == T{ b: true }; // == requires drop + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_makes_imm.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_makes_imm.exp new file mode 100644 index 000000000..1d655d3f6 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_makes_imm.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: WRITEREF_NO_MUTABLE_REFERENCE_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 9)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_makes_imm.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_makes_imm.mvir new file mode 100644 index 000000000..3851d7a61 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_makes_imm.mvir @@ -0,0 +1,17 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let x_ref: &mut u64; + let imm_ref: &u64; +label b0: + x = 5; + x_ref = &mut x; + imm_ref = freeze(move(x_ref)); + // cannot write to an imm ref, even if it is a frozen mut ref + *move(imm_ref) = 0; + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_on_imm.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_on_imm.exp new file mode 100644 index 000000000..d8e623b9e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_on_imm.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-16: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: FREEZEREF_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_on_imm.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_on_imm.mvir new file mode 100644 index 000000000..c842547a9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_on_imm.mvir @@ -0,0 +1,16 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let imm_ref: &u64; +label b0: + x = 5; + imm_ref = &x; + // cannot freeze an imm ref + imm_ref = freeze(move(imm_ref)); + _ = move(imm_ref); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_valid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_valid.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_valid.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_valid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_valid.mvir new file mode 100644 index 000000000..33dbc09d4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_valid.mvir @@ -0,0 +1,18 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let x_ref: &mut u64; + let imm_ref: &u64; +label b0: + x = 5; + x_ref = &mut x; + // freeze type checks correctly + imm_ref = freeze(move(x_ref)); + _ = move(imm_ref); + + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_wrong_type.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_wrong_type.exp new file mode 100644 index 000000000..d4c5434f9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_wrong_type.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-17: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_wrong_type.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_wrong_type.mvir new file mode 100644 index 000000000..9ffbe66ea --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/freeze_wrong_type.mvir @@ -0,0 +1,17 @@ +//# run +module 0x42.m { + +entry foo() { + let x: u64; + let x_ref: &mut u64; + let imm_ref: &bool; +label b0: + x = 5; + x_ref = &mut x; + // freeze, correct ref kind, wrong type + imm_ref = freeze(move(x_ref)); + _ = move(imm_ref); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_borrow_field.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_borrow_field.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_borrow_field.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_borrow_field.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_borrow_field.mvir new file mode 100644 index 000000000..7e9b9d4d3 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_borrow_field.mvir @@ -0,0 +1,19 @@ +//# publish +module 0x1.M { + struct Foo{ x: T } + + baz(x: u64) { + label b0: + return; + } + + bar(x: Self.Foo) { + let y: &mut u64; + let z: u64; + label b0: + y = &mut (&mut x).Foo::x; + _ = move(y); + Foo { x: z } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_call.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_call.exp new file mode 100644 index 000000000..69762fde1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_call.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-15: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 3)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_call.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_call.mvir new file mode 100644 index 000000000..32e4aeda9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_call.mvir @@ -0,0 +1,15 @@ +//# publish +module 0x1.M { + id(x: T): T { + label b0: + return move(x); + } + + foo(x: T) { + let y: T; + label b0: + y = Self.id(move(x)); + y = copy(y); // type does not have copy + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.mvir new file mode 100644 index 000000000..574f95be0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_imm_borrow_field.mvir @@ -0,0 +1,22 @@ +//# publish +module 0x1.M { + struct Foo{ x: T } + + baz(x: u64) { + label b0: + return; + } + + bar(x: Self.Foo) { + let ref: &Self.Foo; + let y: &u64; + let z: u64; + label b0: + ref = &x; + y = &(&x).Foo::x; + _ = move(ref); + _ = move(y); + Foo { x: z } = move(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.mvir new file mode 100644 index 000000000..d9ef85f77 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_pack.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct Foo { x: T1, y: T2 } + + foo(x: T): Self.Foo { + let f: Self.Foo; + label b0: + f = Foo { x: 42, y: move(x) }; + return move(f); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp new file mode 100644 index 000000000..6e22edc07 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.mvir new file mode 100644 index 000000000..37c45a848 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_struct_non_nominal_resource.mvir @@ -0,0 +1,12 @@ +//# publish +module 0x1.M { + struct R { b: bool } + struct Box { x: T } + + foo(x: Self.Box): Self.Box { + let y: Self.Box; + label b0: + y = copy(x); // type does not have copy + return move(y); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_all.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_all.exp new file mode 100644 index 000000000..1a4232f28 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_all.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_all.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_all.mvir new file mode 100644 index 000000000..0e418042a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_all.mvir @@ -0,0 +1,9 @@ +//# publish +module 0x1.M { + foo(x: T): T { + let y: T; + label b0: + y = copy(x); // generic does not have copy + return move(y); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_resource.exp new file mode 100644 index 000000000..1a4232f28 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_resource.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_resource.mvir new file mode 100644 index 000000000..7442838c9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_type_param_resource.mvir @@ -0,0 +1,9 @@ +//# publish +module 0x1.M { + foo(x: T) { + let y: T; + label b0: + y = copy(x); // generic does not have copy + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.exp new file mode 100644 index 000000000..59701471c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.mvir new file mode 100644 index 000000000..61d1cc178 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_abilities_unpack.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x1.M { + struct Foo { x: T } + + baz(x: Self.Foo) { + let y: T; + label b0: + Foo { x: y } = move(x); + return; // unused type parameter value without drop + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.mvir new file mode 100644 index 000000000..c3095185b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_call.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.M { + struct Foo { f: bool } + + public id(x: T): T { + label b0: + return move(x); + } + + public bar(x: T1, y: T2) { + label b0: + abort 0; + } + + foo() { + let x: Self.Foo; + label b0: + _ = Self.id(3); + x = Self.id(Foo { f: false }); + Self.bar(move(x), false); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.mvir new file mode 100644 index 000000000..317dbb6e7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow.mvir @@ -0,0 +1,9 @@ +//# publish +module 0x1.M { + struct X has drop { v: u64 } + struct S has drop { f: T } + t(s: Self.S): u64 { + label b0: + return *(&(&(&s).S::f).X::v); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow_after_call.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow_after_call.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow_after_call.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow_after_call.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow_after_call.mvir new file mode 100644 index 000000000..6e228febb --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_field_borrow_after_call.mvir @@ -0,0 +1,14 @@ +//# publish + +module 0x1.M { + struct X has drop { v: u64 } + id(x: &T): &T { + label b0: + return move(x); + } + + t(x: Self.X): u64 { + label b0: + return *(&Self.id(&x).X::v); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_function_def.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_function_def.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_function_def.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_function_def.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_function_def.mvir new file mode 100644 index 000000000..1571fe64b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_function_def.mvir @@ -0,0 +1,19 @@ +//# publish + +// This test checks that for each function definition +// 1) type parameters have correct kind constraints +// 2) variables have correct types + +module 0x1.M { + public id(x: T): T { + label b0: + return move(x); + } + + public foo(x1: T4, x2: T3) { + let x3: T2; + let x4: T1; + label b0: + abort 0; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_id_function.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_id_function.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_id_function.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_id_function.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_id_function.mvir new file mode 100644 index 000000000..a49ba03b6 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_id_function.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x1.M { + public id(x: T): T { + label b0: + return move(x); + } +} + + + +//# run +module 0x42.m { +import 0x1.M; + +entry foo() { + let x: u64; + let y: u64; +label b0: + y = 42; + x = M.id(move(y)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_function.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_function.exp new file mode 100644 index 000000000..11bd781f9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_function.exp @@ -0,0 +1,19 @@ +processed 3 tasks + +task 1 'run'. lines 21-30: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x1::M, + indices: [], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'run'. lines 32-41: +Error: Function execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: 0x1::M, + indices: [], + offsets: [(FunctionDefinitionIndex(1), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_function.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_function.mvir new file mode 100644 index 000000000..b1bfbf6fe --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_function.mvir @@ -0,0 +1,41 @@ +//# publish +module 0x1.M { + struct R has key { f: bool } + + public foo(x: T) { + label b0: + abort 0; + } + + public bar(x: T3, y: T2, z: T1) { + label b0: + abort 0; + } + + public r(): Self.R { + label b0: + return R { f: false }; + } +} + +//# run +module 0x1.m { +import 0x1.M; + +entry foo() { +label b0: + M.foo(0); + abort 0; +} +} + +//# run +module 0x2.m { +import 0x1.M; + +entry foo() { +label b0: + M.bar(false, M.r(), 0); + abort 0; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.exp new file mode 100644 index 000000000..fc5a4436b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.mvir new file mode 100644 index 000000000..e0c3b495c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_import_struct.mvir @@ -0,0 +1,28 @@ +//# publish +module 0x1.M { + struct Foo has key { x: T } + + struct Bar { x: T3, y: T2, z: T1 } +} + +//# run +module 0x1.m { +import 0x1.M; + +entry foo() { + let x: M.Foo; +label b0: + return; +} +} + +//# run +module 0x2.m { +import 0x1.M; + +entry foo() { + let x: M.Bar, bool>; +label b0: + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.mvir new file mode 100644 index 000000000..7e91ea293 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_option.mvir @@ -0,0 +1,39 @@ +//# publish + +// example using generics in a few common/interesting/non-trivial ways +module 0x42.Option { + import 0x1.vector; + + struct T has copy, drop, store { + v: vector + } + + public none(): Self.T { + label b0: + return T { v: vector.empty() }; + } + + public some(e: E): Self.T { + let v: vector; + label b0: + v = vector.empty(); + vector.push_back(&mut v, move(e)); + return T { v: move(v) }; + } + + public unwrap_or(x: Self.T, e: E): E { + let v: vector; + label b0: + T { v: v } = move(x); + jump_if (vector.is_empty(&v)) b2; + label b1: + return vector.pop_back(&mut v); + label b2: + return move(e); + } + + public really_none(): Self.T { + label b0: + return Self.unwrap_or>(Self.none>(), Self.none()); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.mvir new file mode 100644 index 000000000..7d49fc36f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_pack.mvir @@ -0,0 +1,24 @@ +//# publish +module 0x1.M { + struct Foo { x: T } + + foo() { + let x: Self.Foo; + label b0: + x = Foo { x : 42 }; // valid + abort 0; + } +} + +//# publish +module 0x1.N { + struct Foo { x: T1, y: T2 } + struct Bar has key { f: bool } + + foo() { + let x: Self.Foo; + label b0: + x = Foo { x : 42, y: Bar { f: false } }; // valid + abort 0; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.mvir new file mode 100644 index 000000000..4c98c1df9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_struct_def.mvir @@ -0,0 +1,10 @@ +//# publish + +// This test checks that for each struct definition +// 1) type parameters have correct kind constraints +// 2) fields have correct types + +module 0x1.M { + struct Foo { x: T } + struct Bar { x1: T2, x2: T3, x3: T4, x4: T1 } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.mvir new file mode 100644 index 000000000..74b746057 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/generic_unpack.mvir @@ -0,0 +1,25 @@ +//# publish +module 0x1.M { + struct Foo { x: T } + + foo() { + let x: u64; + label b0: + Foo { x: x } = Foo { x: 42 }; // valid + return; + } +} + +//# publish +module 0x1.N { + struct Foo { x: T1, y: T2 } + + foo() { + let x: u64; + let y: bool; + label b0: + // valid + Foo { x: x, y: y } = Foo { x: 42, y: true }; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.exp new file mode 100644 index 000000000..3a1e5ebb8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.exp @@ -0,0 +1,1720 @@ +processed 191 tasks + +task 0 'run'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 1 'run'. lines 15-24: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 2 'run'. lines 26-35: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 3 'run'. lines 37-46: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 4 'run'. lines 48-57: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 5 'run'. lines 59-68: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 6 'run'. lines 70-79: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 7 'run'. lines 81-90: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 8 'run'. lines 92-101: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 9 'run'. lines 103-112: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 10 'run'. lines 114-123: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 11 'run'. lines 125-134: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 12 'publish'. lines 136-144: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 13 'publish'. lines 146-154: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 14 'publish'. lines 156-168: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 15 'run'. lines 169-178: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 16 'run'. lines 180-189: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 17 'run'. lines 191-200: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 18 'run'. lines 202-211: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 19 'run'. lines 213-222: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 20 'run'. lines 224-233: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 21 'run'. lines 235-244: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 22 'run'. lines 246-255: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 23 'run'. lines 257-266: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 24 'run'. lines 268-277: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 25 'run'. lines 279-288: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 26 'run'. lines 290-299: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 27 'publish'. lines 301-309: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 28 'publish'. lines 311-319: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 29 'publish'. lines 321-333: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 30 'run'. lines 334-343: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 31 'run'. lines 345-354: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 32 'run'. lines 356-365: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 33 'run'. lines 367-376: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 34 'run'. lines 378-387: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 35 'run'. lines 389-398: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 36 'run'. lines 400-409: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 37 'run'. lines 411-420: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 38 'run'. lines 422-431: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 39 'run'. lines 433-442: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 40 'run'. lines 444-453: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 41 'run'. lines 455-464: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 42 'publish'. lines 466-474: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 43 'publish'. lines 476-484: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 44 'publish'. lines 486-498: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 45 'run'. lines 499-508: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 46 'run'. lines 510-519: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 47 'run'. lines 521-530: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 48 'run'. lines 532-541: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 49 'run'. lines 543-552: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 50 'run'. lines 554-563: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 51 'run'. lines 565-574: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 52 'run'. lines 576-585: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 53 'run'. lines 587-596: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 54 'run'. lines 598-607: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 55 'run'. lines 609-618: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 56 'run'. lines 620-629: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 57 'publish'. lines 631-639: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 58 'publish'. lines 641-649: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 59 'publish'. lines 651-663: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 60 'run'. lines 664-673: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 61 'run'. lines 675-684: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 62 'run'. lines 686-695: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 63 'run'. lines 697-706: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 64 'run'. lines 708-717: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 65 'run'. lines 719-728: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 66 'run'. lines 730-739: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 67 'run'. lines 741-750: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 68 'run'. lines 752-761: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 69 'run'. lines 763-772: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 70 'run'. lines 774-783: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 71 'run'. lines 785-794: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 72 'publish'. lines 796-804: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 73 'publish'. lines 806-814: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 74 'publish'. lines 816-828: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 75 'run'. lines 829-838: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 76 'run'. lines 840-849: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 77 'run'. lines 851-860: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 78 'run'. lines 862-871: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 79 'run'. lines 873-882: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 80 'run'. lines 884-893: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 81 'run'. lines 895-904: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 82 'run'. lines 906-915: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 83 'run'. lines 917-926: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 84 'run'. lines 928-937: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 85 'run'. lines 939-948: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 86 'run'. lines 950-959: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 87 'publish'. lines 961-969: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 88 'publish'. lines 971-979: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 89 'publish'. lines 981-993: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 90 'run'. lines 994-1003: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 91 'run'. lines 1005-1014: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 92 'run'. lines 1016-1025: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 93 'run'. lines 1027-1036: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 94 'run'. lines 1038-1047: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 95 'run'. lines 1049-1058: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 96 'run'. lines 1060-1069: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 97 'run'. lines 1071-1080: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 98 'run'. lines 1082-1091: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 99 'run'. lines 1093-1102: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 100 'run'. lines 1104-1113: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 101 'run'. lines 1115-1124: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 102 'publish'. lines 1126-1134: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 103 'publish'. lines 1136-1144: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 104 'publish'. lines 1146-1158: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 105 'run'. lines 1159-1168: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 106 'run'. lines 1170-1179: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 107 'run'. lines 1181-1190: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 108 'run'. lines 1192-1201: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 109 'run'. lines 1203-1212: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 110 'run'. lines 1214-1223: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 111 'run'. lines 1225-1234: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 112 'run'. lines 1236-1245: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 113 'run'. lines 1247-1256: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 114 'run'. lines 1258-1267: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 115 'publish'. lines 1269-1277: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 116 'publish'. lines 1279-1290: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 117 'run'. lines 1291-1300: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 118 'run'. lines 1302-1311: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 119 'run'. lines 1313-1322: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 120 'run'. lines 1324-1333: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 121 'run'. lines 1335-1344: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 122 'run'. lines 1346-1355: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 123 'run'. lines 1357-1366: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 124 'run'. lines 1368-1377: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 125 'run'. lines 1379-1388: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 126 'run'. lines 1390-1399: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 127 'publish'. lines 1401-1409: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 128 'publish'. lines 1411-1423: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: EQUALITY_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 129 'run'. lines 1424-1433: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 130 'run'. lines 1435-1444: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 131 'run'. lines 1446-1455: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 132 'run'. lines 1457-1466: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 133 'run'. lines 1468-1477: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 134 'run'. lines 1479-1488: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 135 'run'. lines 1490-1499: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 136 'run'. lines 1501-1510: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 137 'run'. lines 1512-1521: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 138 'run'. lines 1523-1534: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 139 'run'. lines 1535-1544: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 140 'run'. lines 1546-1555: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 141 'run'. lines 1557-1566: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 142 'run'. lines 1568-1577: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 143 'run'. lines 1579-1588: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 144 'run'. lines 1590-1599: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 145 'run'. lines 1601-1610: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 146 'run'. lines 1612-1621: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 147 'run'. lines 1623-1632: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 148 'run'. lines 1634-1645: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 149 'run'. lines 1646-1655: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 150 'run'. lines 1657-1666: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 151 'run'. lines 1668-1677: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 152 'run'. lines 1679-1688: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 153 'run'. lines 1690-1699: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 154 'run'. lines 1701-1710: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 155 'run'. lines 1712-1721: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 156 'run'. lines 1723-1732: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 157 'run'. lines 1734-1743: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 158 'run'. lines 1745-1756: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 159 'run'. lines 1757-1766: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 160 'run'. lines 1768-1777: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 161 'run'. lines 1779-1788: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 162 'run'. lines 1790-1799: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 163 'run'. lines 1801-1810: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 164 'run'. lines 1812-1821: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 165 'run'. lines 1823-1832: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 166 'run'. lines 1834-1843: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 167 'run'. lines 1845-1854: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 168 'run'. lines 1856-1867: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 169 'run'. lines 1868-1877: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 170 'run'. lines 1879-1888: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 171 'run'. lines 1890-1899: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 172 'run'. lines 1901-1910: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 173 'run'. lines 1912-1921: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 174 'run'. lines 1923-1932: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 175 'run'. lines 1934-1943: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 176 'run'. lines 1945-1954: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 177 'publish'. lines 1956-1964: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 178 'publish'. lines 1966-1974: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 179 'publish'. lines 1976-1988: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 180 'run'. lines 1989-1998: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 181 'run'. lines 2000-2009: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 182 'run'. lines 2011-2020: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 183 'run'. lines 2022-2031: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 184 'run'. lines 2033-2042: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 185 'run'. lines 2044-2053: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 186 'run'. lines 2055-2064: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 187 'run'. lines 2066-2075: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 188 'publish'. lines 2077-2085: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 189 'publish'. lines 2087-2095: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 190 'publish'. lines 2097-2105: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: INTEGER_OP_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.mvir new file mode 100644 index 000000000..acd94ba77 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integer_binary_operators_types_mismatch.mvir @@ -0,0 +1,2105 @@ +//# run +module 0x42.m { + +// tests multiple type mismatches for int operations +// !!!! generated file, do NOT edit manually !!!! + +// operator + +entry foo() { +label b0: + _ = 0u8 + 0u64; + return; +} +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 + 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 + 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 + 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 + 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 + 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 + true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true + 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true + true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 + 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 + 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 + 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 + (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) + 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) + (R { x: true }); + return; + } +} + + + +// operator - +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 - 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 - 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 - 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 - 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 - 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 - 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 - true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true - 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true - true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 - 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 - 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 - 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 - (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) - 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) - (R { x: true }); + return; + } +} + + + +// operator * +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 * 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 * 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 * 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 * 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 * 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 * 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 * true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true * 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true * true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 * 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 * 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 * 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 * (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) * 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) * (R { x: true }); + return; + } +} + + + +// operator / +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 / 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 / 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 / 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 / 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 / 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 / 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 / true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true / 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true / true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 / 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 / 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 / 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 / (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) / 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) / (R { x: true }); + return; + } +} + + + +// operator & +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 & 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 & 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 & 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 & 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 & 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 & 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 & true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true & 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true & true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 & 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 & 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 & 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 & (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) & 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) & (R { x: true }); + return; + } +} + + + +// operator | +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 | 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 | 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 | 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 | 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 | 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 | 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 | true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true | 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true | true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 | 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 | 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 | 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 | (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) | 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) | (R { x: true }); + return; + } +} + + + +// operator ^ +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 ^ 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 ^ 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 ^ 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 ^ 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 ^ 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 ^ 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 ^ true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true ^ 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true ^ true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 ^ 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 ^ 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 ^ 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 ^ (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) ^ 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) ^ (R { x: true }); + return; + } +} + + + +// operator == +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 == 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 == 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 == 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 == 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 == 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 == 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 == true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true == 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 == 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 == 0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 == (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) == 0; + return; + } +} + + +// operator != +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 != 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 != 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 != 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 != 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 != 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 != 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 != true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true != 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 != 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 != 0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 != (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) != 0; + return; + } +} + + + +// operator < +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 < 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 < 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 < 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 < 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 < 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 < 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 < true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true < 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 < 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 < 0; + return; +} + +} + +// operator > +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 > 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 > 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 > 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 > 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 > 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 > 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 > true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true > 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 > 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 > 0; + return; +} + +} + +// operator <= +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 <= 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 <= 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 <= 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 <= 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 <= 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 <= 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 <= true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true <= 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 <= 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 <= 0; + return; +} + +} + +// operator >= +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 >= 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u8 >= 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 >= 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u64 >= 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 >= 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0u128 >= 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 >= true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true >= 0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 >= 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 >= 0; + return; +} + +} + +// operator << +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 << true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 << 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 << 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 << 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true << 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true << true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 << 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 << 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 << (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) << 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) << (R { x: true }); + return; + } +} + + + +// operator >> +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 >> true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 >> 0x0; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 >> 0u64; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0 >> 0u128; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true >> 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = true >> true; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 >> 0u8; + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { +label b0: + _ = 0x0 >> 0x0; + return; +} + +} + +//# publish +module 0x42.M { + struct R { x: bool } + f() { + label b0: + _ = 0 >> (R { x: true }); + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + g() { + label b0: + _ = (R { x: true }) >> 0; + return; + } +} + +//# publish +module 0x42.M { + struct R { x: bool } + h() { + label b0: + _ = (R { x: true }) >> (R { x: true }); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integers_valid.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integers_valid.exp new file mode 100644 index 000000000..2301000e5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integers_valid.exp @@ -0,0 +1 @@ +processed 6 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integers_valid.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integers_valid.mvir new file mode 100644 index 000000000..3738c081c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/integers_valid.mvir @@ -0,0 +1,125 @@ +//# publish +module 0x42.tu8 { +test() { +let x: u8; +label l0: + x = 0u8; + x = 100u8; + x = 1u8 + 1u8; + x = 1u8 - 1u8; + x = 1u8 * 1u8; + x = 1u8 / 1u8; + x = 1u8 % 1u8; + x = 1u8 & 1u8; + x = 1u8 | 1u8; + x = 1u8 ^ 1u8; + x = 1u8 << 1u8; + x = 1u8 >> 1u8; + return; +} +} + +//# publish +module 0x42.tu16 { +test() { +let x: u16; +label l0: + x = 0u16; + x = 100u16; + x = 1u16 + 1u16; + x = 1u16 - 1u16; + x = 1u16 * 1u16; + x = 1u16 / 1u16; + x = 1u16 % 1u16; + x = 1u16 & 1u16; + x = 1u16 | 1u16; + x = 1u16 ^ 1u16; + x = 1u16 << 1u8; + x = 1u16 >> 1u8; + return; +} +} + +//# publish +module 0x42.tu32 { +test() { +let x: u32; +label l0: + x = 0u32; + x = 100u32; + x = 1u32 + 1u32; + x = 1u32 - 1u32; + x = 1u32 * 1u32; + x = 1u32 / 1u32; + x = 1u32 % 1u32; + x = 1u32 & 1u32; + x = 1u32 | 1u32; + x = 1u32 ^ 1u32; + x = 1u32 << 1u8; + x = 1u32 >> 1u8; + return; +} +} + +//# publish +module 0x42.tu64 { +test() { +let x: u64; +label l0: + x = 0u64; + x = 100u64; + x = 1u64 + 1u64; + x = 1u64 - 1u64; + x = 1u64 * 1u64; + x = 1u64 / 1u64; + x = 1u64 % 1u64; + x = 1u64 & 1u64; + x = 1u64 | 1u64; + x = 1u64 ^ 1u64; + x = 1u64 << 1u8; + x = 1u64 >> 1u8; + return; +} +} + +//# publish +module 0x42.tu128 { +test() { +let x: u128; +label l0: + x = 0u128; + x = 100u128; + x = 1u128 + 1u128; + x = 1u128 - 1u128; + x = 1u128 * 1u128; + x = 1u128 / 1u128; + x = 1u128 % 1u128; + x = 1u128 & 1u128; + x = 1u128 | 1u128; + x = 1u128 ^ 1u128; + x = 1u128 << 1u8; + x = 1u128 >> 1u8; + return; +} +} + +//# publish +module 0x42.tu256 { +test() { +let x: u256; +label l0: + x = 0u256; + x = 100u256; + x = 1u256 + 1u256; + x = 1u256 - 1u256; + x = 1u256 * 1u256; + x = 1u256 / 1u256; + x = 1u256 % 1u256; + x = 1u256 & 1u256; + x = 1u256 | 1u256; + x = 1u256 ^ 1u256; + x = 1u256 << 1u8; + x = 1u256 >> 1u8; + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write.exp new file mode 100644 index 000000000..9927b5107 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-18: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: WRITEREF_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write.mvir new file mode 100644 index 000000000..e6e954b2c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_field_write.mvir @@ -0,0 +1,18 @@ +//# publish +module 0x42.Test { + struct T{fr: bool} + + public new(): Self.T { + label b0: + return T{fr: false}; + } + + public no(this: &mut Self.T) { + let x: &mut bool; + label b0: + x = &mut move(this).T::fr; + // type mismatch on assignment/mutation + *move(x) = 0; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resource_write.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resource_write.exp new file mode 100644 index 000000000..b1ff69815 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resource_write.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::RTest'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x42::RTest, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resource_write.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resource_write.mvir new file mode 100644 index 000000000..a931053f2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/invalid_resource_write.mvir @@ -0,0 +1,14 @@ +//# publish +module 0x42.RTest { + struct Coin has store { value: u64 } + struct T { f: Self.Coin } + + public update(t: &mut Self.T, i: Self.Coin) { + let x: &mut Self.Coin; + label b0: + x = &mut move(t).T::f; + // cannot assign to ref where type does not have drop + *move(x) = move(i); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.exp new file mode 100644 index 000000000..5e1d9de7a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { + major_status: BORROWFIELD_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Token, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.mvir new file mode 100644 index 000000000..3a9807281 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_borrow_from_imm_ref.mvir @@ -0,0 +1,25 @@ +//# publish +module 0x42.Token { + struct T{value: u64} + public new(m: u64): Self.T { + label b0: + return T{value: copy(m)}; + } + public destroy(t: Self.T) { + let value: u64; + label b0: + T {value} = move(t); + return; + } + + public bump_value(this: &Self.T) { + let val: &mut u64; + let x: u64; + label b0: + // cannot mut borrow imm reff + val = &mut move(this).T::value; + x = *copy(val) + 1; + *move(val) = copy(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.mvir new file mode 100644 index 000000000..aeee94c83 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_from_get_resource.mvir @@ -0,0 +1,65 @@ +//# publish +module 0x42.Token { + import 0x1.signer; + + struct T has key {balance: u64} + + public new(balance: u64): Self.T { + label b0: + return T{balance: copy(balance)}; + } + + public value(this: &Self.T): u64 { + let b: u64; + let b_ref: &u64; + label b0: + b_ref = &move(this).T::balance; + b = *move(b_ref); + return move(b); + } + + public bump(this: &mut Self.T) { + let val: &mut u64; + let x: u64; + label b0: + val = &mut move(this).T::balance; + x = *copy(val) + 1; + *move(val) = copy(x); + return; + } + + public publish(account: &signer, t: Self.T) { + label b0: + abort(0); + } + + fake(addr: address): &mut Self.T { label b0: abort(0); } + + public test(account: &signer) { + let z: Self.T; + let addr1: address; + let struct1: &mut Self.T; + let imm_struct1: &Self.T; + let struct1_original_balance: u64; + let struct1_new_balance: u64; + label b0: + z = Self.new(0); + Self.publish(copy(account), move(z)); + + addr1 = signer.address_of(move(account)); + // returns mut reference, test its usage + struct1 = Self.fake(copy(addr1)); + + imm_struct1 = freeze(copy(struct1)); + struct1_original_balance = Self.value(move(imm_struct1)); + assert(move(struct1_original_balance) == 0, 42); + + Self.bump(copy(struct1)); + + imm_struct1 = freeze(move(struct1)); + struct1_new_balance = Self.value(move(imm_struct1)); + assert(move(struct1_new_balance) == 1, 43); + + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref.exp new file mode 100644 index 000000000..db9153197 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-33: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Token'. Got VMError: { + major_status: CALL_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Token, + indices: [(FunctionDefinition, 2)], + offsets: [(FunctionDefinitionIndex(2), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref.mvir new file mode 100644 index 000000000..615090275 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/mut_call_with_imm_ref.mvir @@ -0,0 +1,33 @@ +//# publish +module 0x42.Token { + struct T{value: u64} + public new(m: u64): Self.T { + label b0: + return T{value: copy(m)}; + } + public destroy(t: Self.T) { + let value: u64; + label b0: + T {value} = move(t); + return; + } + + public read_value(this: &Self.T): u64 { + let val: &u64; + label b0: + val = ©(this).T::value; + // type mismatch, cannot make imm to mut + Self.bump_value(move(this)); + return *move(val); + } + + public bump_value(this: &mut Self.T) { + let val: &mut u64; + let x: u64; + label b0: + val = &mut move(this).T::value; + x = *copy(val) + 1; + *move(val) = copy(x); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp new file mode 100644 index 000000000..9e70f3442 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.exp @@ -0,0 +1,46 @@ +processed 6 tasks + +task 1 'publish'. lines 10-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x1::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 2 'publish'. lines 24-36: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: POP_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x1::M3, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 3 'publish'. lines 38-49: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::M4, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 4 'publish'. lines 51-61: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::M5, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 5 'publish'. lines 63-74: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M9'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M9, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.mvir new file mode 100644 index 000000000..5e843b4c5 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_bad.mvir @@ -0,0 +1,74 @@ +//# publish + +// This file contains tests checking that type arguments used in phantom position +// (phantom arguments) are not considered when deriving the abilities for a struct. + +module 0x1.M1 { + struct NoAbilities { a: bool } +} + +//# publish +module 0x1.M2 { + import 0x1.M1; + + struct HasDrop has drop { a: bool } + + // `WriteRef` requires drop + f(ref: &mut Self.HasDrop) { + label b0: + *move(ref) = HasDrop { a : true }; + return; + } +} + +//# publish +module 0x1.M3 { + import 0x1.M1; + + struct HasDrop has drop { a: bool } + + // `Pop` requires drop + f() { + label b0: + _ = HasDrop { a: true }; + return; + } + } + +//# publish + module 0x1.M4 { + import 0x1.M1; + + struct HasDrop has drop { a: bool } + + // Leaving value in local requires drop + f(x: Self.HasDrop) { + label b0: + return; + } + } + +//# publish + module 0x1.M5 { + import 0x1.M1; + struct HasCopy has copy { a : bool } + + // `CopyLoc` requires copy + f(x: Self.HasCopy): Self.HasCopy * Self.HasCopy { + label b0: + return (copy(x), move(x)); + } + } + +//# publish +module 0x1.M9 { + import 0x1.M1; + + struct HasStore has store { a: bool } + struct RequireStore { a: bool } + + f(): Self.RequireStore> { + label b0: + return RequireStore> { a: true }; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.mvir new file mode 100644 index 000000000..1a54ba91d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/bytecode_ops_abilities_ok.mvir @@ -0,0 +1,45 @@ +//# publish + +// Test checking that type arguments used in phantom position (phantom arguments) +// are not considered when deriving the abilities for a struct by checking against +// abilities required for specific bytecode operatiosn. + +module 0x1.M { + struct NoAbilities { a: bool } + struct HasDrop has drop { a: bool } + struct HasCopy has copy { a : bool } + struct HasStore has store { a: bool } + struct HasKey has key { a : bool } + struct RequireStore { a: bool } + + // `WriteRef` requires drop + f1(ref: &mut Self.HasDrop) { + label b0: + *move(ref) = HasDrop { a: true }; + return; + } + + // `Pop` requires drop + f2() { + label b0: + _ = HasDrop { a: true }; + return; + } + + // Leaving value in local requires drop + f3(x: Self.HasDrop) { + label b0: + return; + } + + // `CopyLoc` requires copy + f4(x: Self.HasCopy): Self.HasCopy * Self.HasCopy { + label b0: + return (copy(x), move(x)); + } + + f8(): Self.RequireStore> { + label b0: + return RequireStore> { a: true }; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp new file mode 100644 index 000000000..4df09dd1d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.exp @@ -0,0 +1,37 @@ +processed 6 tasks + +task 1 'publish'. lines 7-15: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M2, + indices: [(FieldDefinition, 0), (StructDefinition, 1)], + offsets: [], +} + +task 2 'publish'. lines 17-34: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M3, + indices: [(FieldDefinition, 0), (StructDefinition, 5)], + offsets: [], +} + +task 3 'publish'. lines 36-46: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M4, + indices: [(Signature, 0), (FunctionDefinition, 1)], + offsets: [], +} + +task 5 'publish'. lines 60-75: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M5, + indices: [(Signature, 0), (FunctionDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.mvir new file mode 100644 index 000000000..ced372110 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_bad.mvir @@ -0,0 +1,75 @@ +//# publish +module 0x1.M1 { + struct NoAbilities { a: bool } + struct HasAbilities has drop, copy, store, key { a: bool } +} + +//# publish +module 0x1.M2 { + import 0x1.M1; + + struct S1 { a: bool } + struct S2 { + a: Self.S1>, + } +} + +//# publish +module 0x1.M3 { + import 0x1.M1; + + struct HasDrop has drop { a: bool } + struct HasCopy has copy { a: bool } + struct HasStore has store { a: bool } + struct HasKey has key { a: bool } + + struct S1 { a: bool } + struct S2 { + a: Self.S1< Self.HasDrop, + Self.HasCopy, + Self.HasStore, + Self.HasKey + > + } +} + +//# publish +module 0x1.M4 { + import 0x1.M1; + + f1() { label b0: return; } + f2() { + label b0: + Self.f1>(); + return; + } +} + + +//# publish +module 0x1.M3Valid { + import 0x1.M1; + + struct HasDrop has drop { a: bool } + struct HasCopy has copy { a: bool } + struct HasStore has store { a: bool } + struct HasKey has key { a: bool } + +} + +//# publish +module 0x1.M5 { + import 0x1.M1; + import 0x1.M3Valid; + + f1() { label b0: return; } + f2() { + label b0: + Self.f1< M3Valid.HasDrop, + M3Valid.HasCopy, + M3Valid.HasStore, + M3Valid.HasKey + >(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.mvir new file mode 100644 index 000000000..c59b6a17d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/constraints_abilities_ok.mvir @@ -0,0 +1,41 @@ +//# publish +module 0x1.M { + struct NoAbilities { a: bool } + struct HasDrop has drop { a: bool } + struct HasCopy has copy { a: bool } + struct HasStore has store { a: bool } + struct HasKey has key { a: bool } + struct HasAbilities has drop, copy, store, key { a: bool } + + struct S1 { a: bool } + struct S2 { + a: Self.S1>, + } + + struct S3 { a: bool } + struct S4 { + a: Self.S3< Self.HasDrop, + Self.HasCopy, + Self.HasStore, + Self.HasKey + > + } + + f1() { label b0: return; } + f2() { + label b0: + Self.f1>(); + return; + } + + f3() { label b0: return; } + f4() { + label b0: + Self.f3< Self.HasDrop, + Self.HasCopy, + Self.HasStore, + Self.HasKey + >(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp new file mode 100644 index 000000000..43e65b417 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.exp @@ -0,0 +1,37 @@ +processed 5 tasks + +task 1 'publish'. lines 16-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x1::M2, + indices: [(StructDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 23-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x1::M3, + indices: [(StructDefinition, 0)], + offsets: [], +} + +task 3 'publish'. lines 30-35: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x1::M4, + indices: [(StructDefinition, 0)], + offsets: [], +} + +task 4 'publish'. lines 37-42: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { + major_status: FIELD_MISSING_TYPE_ABILITY, + sub_status: None, + location: 0x1::M5, + indices: [(StructDefinition, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.mvir new file mode 100644 index 000000000..27420506f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_bad.mvir @@ -0,0 +1,42 @@ +//# publish + +// Negative version of tests in fields_abilities_ok instantiating the non-phantom +// parameter with a type without the required abilities. + +module 0x1.M1 { + struct NoAbilities { a: bool } + + struct HasDrop has drop { a: bool } + struct HasCopy has copy { a : bool } + struct HasStore has store { a : bool } + struct HasKey has key { a : bool } + +} + +//# publish +module 0x1.M2 { + import 0x1.M1; + + struct S has drop { a: M1.HasDrop } +} + +//# publish +module 0x1.M3 { + import 0x1.M1; + + struct S has copy { a: M1.HasCopy } +} + +//# publish +module 0x1.M4 { + import 0x1.M1; + + struct S has store { a: M1.HasStore } +} + +//# publish +module 0x1.M5 { + import 0x1.M1; + + struct S has key { a: M1.HasStore } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.mvir new file mode 100644 index 000000000..f42204d00 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/fields_abilities_ok.mvir @@ -0,0 +1,18 @@ +//# publish + +// This module checks that phantom arguments are not considered by checking against +// the abilities required for the fields of a struct. + +module 0x1.M { + struct NoAbilities { a: bool } + + struct HasDrop has drop { a: bool } + struct HasCopy has copy { a : bool } + struct HasStore has store { a : bool } + struct HasKey has key { a : bool } + + struct S1 has drop { a: Self.HasDrop } + struct S2 has copy { a: Self.HasCopy } + struct S3 has store { a: Self.HasStore } + struct S4 has key { a: Self.HasStore } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp new file mode 100644 index 000000000..2dd0de877 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.exp @@ -0,0 +1,55 @@ +processed 6 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x1::M1, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} + +task 1 'publish'. lines 13-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x1::M2, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} + +task 2 'publish'. lines 21-28: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x1::M3, + indices: [(FieldDefinition, 0), (StructDefinition, 1)], + offsets: [], +} + +task 3 'publish'. lines 30-39: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x1::M4, + indices: [(FieldDefinition, 0), (StructDefinition, 2)], + offsets: [], +} + +task 4 'publish'. lines 41-47: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { + major_status: INVALID_PHANTOM_TYPE_PARAM_POSITION, + sub_status: None, + location: 0x1::M5, + indices: [(FieldDefinition, 0), (StructDefinition, 0)], + offsets: [], +} + +task 5 'publish'. lines 49-56: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M6'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x1::M6, + indices: [(FieldDefinition, 0), (StructDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.mvir new file mode 100644 index 000000000..2eeaa025b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_bad.mvir @@ -0,0 +1,56 @@ +//# publish + +// Tests checking incorrect struct declarations using phantom parameters +// in illegal positions. + +module 0x1.M1 { + // A phantom parameter cannot be used as the type of a field + struct S1 { + a: T + } +} + +//# publish +module 0x1.M2 { + // The parameter of vector is non-phantom and a phantom parameter shouldn't be allowed in that position + struct S2 { + a: vector + } +} + +//# publish +module 0x1.M3 { + // A phantom parameter cannot be used as the argument to a non-phantom parameter + struct S1 { f: bool } + struct S2 { + a: Self.S1 + } +} + +//# publish +module 0x1.M4 { + // More complicated test where the phantom position violation is inside another + // type argument. + struct S1 { a: T} + struct S2 { a : T } + struct S3 { + a: Self.S1> + } +} + +//# publish +module 0x1.M5 { + // Mixing phantom and non-phantom parameters + struct S { + a: T2 + } +} + +//# publish +module 0x1.M6 { + // Phantom parameters should satisfy constraints + struct S1 { a: bool } + struct S2 { + a: Self.S1 + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp new file mode 100644 index 000000000..fc5a4436b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.exp @@ -0,0 +1 @@ +processed 3 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.mvir new file mode 100644 index 000000000..6cf2dd6cc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/phantom_params/struct_definition_ok.mvir @@ -0,0 +1,47 @@ +//# publish +module 0x1.M1 { + // Not using a phantom parameter at all is ok. + struct S1 { + a: u64 + } + + // Phantom parameters can be used in phantom position. + struct S2 { + a: Self.S1, + b: vector> + } + + // It's ok to not use a non-phantom parameter (backward-compatibility). + struct S3 { + a: u64 + } + + // Mixing phantom and non-phantom parameters + struct S4 { + a: T2, + b: T4 + } +} + +//# publish +module 0x1.M2 { + import 0x1.M1; + + // Phantom position across modules + struct S { + a: M1.S2> + } +} + +//# publish +module 0x1.M3 { + // Phantom parameters should be allowed to be declared with constraints. + + struct S1 { + a: u64 + } + + struct S2 { + a: Self.S1 + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_args_subtype.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_args_subtype.exp new file mode 100644 index 000000000..b6ee37c18 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_args_subtype.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 11-24: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: CALL_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_args_subtype.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_args_subtype.mvir new file mode 100644 index 000000000..bc557a6e6 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_args_subtype.mvir @@ -0,0 +1,24 @@ +//# publish + +module 0x42.Test { + public t(fr: &u64) { + label b0: + _ = move(fr); + return; + } +} + +//# run +module 0x42.m { + +import 0x42.Test; + +entry foo() { + let x: u64; +label b0: + x = 0; + // arg type mismatch, no implicit freeze + Test.t(&mut x); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_subtype.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_subtype.exp new file mode 100644 index 000000000..b1a59d8fc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_subtype.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: RET_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Test, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_subtype.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_subtype.mvir new file mode 100644 index 000000000..047b267f0 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_subtype.mvir @@ -0,0 +1,9 @@ +//# publish + +module 0x42.Test { + public no(r: &mut u64): &u64 { + label b0: + // return type mismatch, no implicit freeze + return move(r); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_type.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_type.exp new file mode 100644 index 000000000..b1a59d8fc --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_type.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-9: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: RET_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Test, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_type.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_type.mvir new file mode 100644 index 000000000..69db36fe7 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/procedure_return_invalid_type.mvir @@ -0,0 +1,9 @@ +//# publish + +module 0x42.Test { + public no(): u64 { + label b0: + // return type mismatch + return false; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.exp new file mode 100644 index 000000000..4d754d64d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M1, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 1 'publish'. lines 12-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M2, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 2 'publish'. lines 23-32: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { + major_status: NUMBER_OF_TYPE_ARGUMENTS_MISMATCH, + sub_status: None, + location: undefined, + indices: [], + offsets: [], +} + +task 3 'publish'. lines 34-44: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M4, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.mvir new file mode 100644 index 000000000..c4c7b958e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param.mvir @@ -0,0 +1,44 @@ +//# publish +module 0x42.M1 { + struct S { t: T } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(s: &Self.S) { + label b0: + return; + } +} + +//# publish +module 0x42.M2 { + struct S { t: T } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(s: &mut Self.S) { + label b0: + return; + } +} + +//# publish +module 0x42.M3 { + struct S { t: T } + + // should get flagged--missing type argument + public bad_sig(s: &Self.S) { + label b0: + return; + } +} + +//# publish +module 0x42.M4 { + struct Box { t: T } + struct S { t: T } + + // should be rejected + public bad_sig(v: Self.Box>): Self.Box> { + label b0: + return move(v); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.exp new file mode 100644 index 000000000..6ce6fc50c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.exp @@ -0,0 +1,46 @@ +processed 5 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M1, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 1 'publish'. lines 13-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M2, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 2 'publish'. lines 25-36: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M3, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 3 'publish'. lines 38-54: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M4, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 4 'publish'. lines 56-72: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M5'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M5, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.mvir new file mode 100644 index 000000000..0eafaeb05 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/ref_type_param_exploits.mvir @@ -0,0 +1,72 @@ +//# publish +module 0x42.M1 { + struct S { t: T } + + // note: T does not have copy + // if this worked, it would be very bad because `T` can be (e.g.) a Coin + public copy_inner(s: &Self.S): T { // should get flagged w/ constraint not satisfied + label b0: + return *&move(s).S::t; + } +} + +//# publish +module 0x42.M2 { + struct S has copy { t: T } + + // note: T does not have copy + // if this worked, it would be very bad because `T` can be (e.g.) a Coin + public copy_direct(s: &Self.S): Self.S { // should get flagged w/ constraint not satisfied + label b0: + return *move(s); + } +} + +//# publish +module 0x42.M3 { + struct S has store { t: T } + + // note: T does not have store + // if this worked, it would be very bad because `T` can be (e.g.) a hot potato + public store_inner(s: &mut Self.S, t: T) { // should get flagged w/ constraint not satisfied + label b0: + *&mut move(s).S::t = move(t); + return; + } +} + +//# publish +module 0x42.M4 { + struct S { t: T } + + public bad_sig(s: &Self.S) { // should get flagged w/ constraint not satisfied + label b0: + return; + } + + public call(): Self.S { + let x: Self.S; + label b0: + x = S { t: 10 }; + Self.bad_sig(&x); + return move(x); + } +} + +//# publish +module 0x42.M5 { + struct S { t: T } + + public bad_sig(s: &Self.S) { // should get flagged w/ constraint not satisfied + label b0: + return; + } + + public call(s: signer): Self.S { + let x: Self.S; + label b0: + x = S { t: move(s) }; + Self.bad_sig(&x); + return move(x); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.exp new file mode 100644 index 000000000..f3a7de94e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: NEGATIVE_STACK_SIZE_WITHIN_BLOCK, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.mvir new file mode 100644 index 000000000..69598020b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/release.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x1.M { + struct Coin { value: u64 } + t(): Self.Coin { + label b0: + // cannot pop without the drop ability + _ = Coin { value: 0 }; + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp new file mode 100644 index 000000000..f8cfe0681 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-14: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Test, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.mvir new file mode 100644 index 000000000..4c7aa6e7a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/resource_instantiate_bad_type.mvir @@ -0,0 +1,14 @@ +//# publish + +module 0x42.Test { + struct A { b: bool } + struct B { b: bool } + struct T { ft: Self.B } + + public t1(x: Self.A): Self.T { + label b0: + // arg type mismatch + return T{ft: move(x)}; + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp new file mode 100644 index 000000000..63337530d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: RET_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 1 'publish'. lines 15-27: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: RET_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} + +task 2 'publish'. lines 29-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 3 'publish'. lines 42-53: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED, + sub_status: None, + location: 0x1::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.mvir new file mode 100644 index 000000000..e0e97d3a4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/return_type_mismatch_and_unused_resource.mvir @@ -0,0 +1,53 @@ +//# publish +module 0x1.M { + struct R { flag: bool } + + // Type checking is done before memory safety checks + // wrong return type + t1(): bool { + let c: Self.R; + label b0: + c = R { flag: false }; + return 0; + } +} + +//# publish +module 0x1.M2 { + // Type checking is done before memory safety checks + // wrong return type + t2(): bool { + let u: u64; + let r: &u64; + label b0: + u = 0; + r = &u; + return move(r); + } +} + +//# publish +module 0x1.M { + struct R { flag: bool } + + t1(): u64 { + let c: Self.R; + label b0: + c = R { flag: false }; + // unused resource + return 0; + } +} + +//# publish +module 0x1.M2 { + t2(): &u64 { + let u: u64; + let r: &u64; + label b0: + u = 0; + r = &u; + // unused resource + return move(r); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc.exp new file mode 100644 index 000000000..c1dde036e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-8: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc.mvir new file mode 100644 index 000000000..93ae9b1c8 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc.mvir @@ -0,0 +1,8 @@ +//# publish +module 0x42.M { + t(s: signer): signer { + label b0: + // signer does not have copy + return copy(s); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc_transitive.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc_transitive.exp new file mode 100644 index 000000000..0325d662d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc_transitive.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc_transitive.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc_transitive.mvir new file mode 100644 index 000000000..f2f48fc7f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_copy_loc_transitive.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x42.M { + struct S has copy { s: T } + t(s: signer): Self.S { + let x: Self.S; + label b0: + x = S { s: move(s) }; + // error signer does not have copy + return copy(x); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_does_not_have_store.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_does_not_have_store.exp new file mode 100644 index 000000000..4f4e59805 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_does_not_have_store.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-15: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M, + indices: [(Signature, 0), (FunctionDefinition, 1)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_does_not_have_store.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_does_not_have_store.mvir new file mode 100644 index 000000000..1678cb52e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_does_not_have_store.mvir @@ -0,0 +1,15 @@ +//# publish +module 0x42.M { + struct S { + f: T, + } + + needs_store() { label b0: return; } + + t(account: &signer, s: signer) { + label b0: + // error signer does not have store + Self.needs_store>(); + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_equality.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_equality.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_equality.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_equality.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_equality.mvir new file mode 100644 index 000000000..e48ec999f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_equality.mvir @@ -0,0 +1,11 @@ +//# run --signers 0x1 +module 0x42.m { + +entry foo(s: signer) { +label b0: + assert(&s == &s, 42); + assert(!(&s != &s), 42); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref.exp new file mode 100644 index 000000000..8bad38762 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-8: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: READREF_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref.mvir new file mode 100644 index 000000000..3a39e5f4b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref.mvir @@ -0,0 +1,8 @@ +//# publish +module 0x42.M { + t(s: &signer): signer { + label b0: + // cannot copy signer + return *copy(s); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref_transitive.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref_transitive.exp new file mode 100644 index 000000000..91e9dd2f2 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref_transitive.exp @@ -0,0 +1,19 @@ +processed 2 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: READREF_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} + +task 1 'publish'. lines 13-23: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M'. Got VMError: { + major_status: READREF_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x42::M, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref_transitive.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref_transitive.mvir new file mode 100644 index 000000000..6b65dc8d6 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_read_ref_transitive.mvir @@ -0,0 +1,23 @@ +//# publish +module 0x42.M { + struct S { s: T } + t(s: signer): Self.S { + let x: Self.S; + label b0: + x = S { s: move(s) }; + // cannot copy signer + return *&x; + } +} + +//# publish +module 0x42.M { + struct S { s: T } + t(s: signer): signer { + let x: Self.S; + label b0: + x = S { s: move(s) }; + // cannot copy signer + return *(&(&x).S::s); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_st_loc.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_st_loc.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_st_loc.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_st_loc.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_st_loc.mvir new file mode 100644 index 000000000..33bfd0c22 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_st_loc.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x42.M { + t(s1: signer, s2: signer) { + label b0: + s1 = move(s2); + return; + } +} + +// Used to be invalid +// Now valid because signer has drop diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_transitive.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_transitive.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_transitive.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_transitive.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_transitive.mvir new file mode 100644 index 000000000..b2eb9336e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_transitive.mvir @@ -0,0 +1,16 @@ +//# publish +module 0x42.M { + struct S has drop { + f: T, + } + + t(s: signer) { + let x: Self.S; + label b0: + x = S { f: move(s) }; + return; + } +} + +// Used to be invalid +// Now valid because signer has drop diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_write_ref.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_write_ref.exp new file mode 100644 index 000000000..6cd67db3f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_write_ref.exp @@ -0,0 +1 @@ +processed 1 task diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_write_ref.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_write_ref.mvir new file mode 100644 index 000000000..bd9d88548 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/signer_write_ref.mvir @@ -0,0 +1,11 @@ +//# publish +module 0x42.M { + t(sref: &mut signer, s: signer) { + label b0: + *copy(sref) = move(s); + return; + } +} + +// Used to be invalid +// Now valid because signer has drop diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.exp new file mode 100644 index 000000000..65b2121ae --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.exp @@ -0,0 +1,46 @@ +processed 5 tasks + +task 0 'publish'. lines 1-12: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M1'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x1::M1, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} + +task 1 'publish'. lines 14-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M2'. Got VMError: { + major_status: STLOC_UNSAFE_TO_DESTROY_ERROR, + sub_status: None, + location: 0x1::M2, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 2 'publish'. lines 27-37: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M3'. Got VMError: { + major_status: READREF_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::M3, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 3 'publish'. lines 39-50: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M4'. Got VMError: { + major_status: WRITEREF_WITHOUT_DROP_ABILITY, + sub_status: None, + location: 0x1::M4, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 4 'publish'. lines 52-62: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::M5'. Got VMError: { + major_status: COPYLOC_WITHOUT_COPY_ABILITY, + sub_status: None, + location: 0x1::M5, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 0)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.mvir new file mode 100644 index 000000000..dbcbbe7cf --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/struct_kind_inference.mvir @@ -0,0 +1,62 @@ +//# publish +// ensure that generic structs instantiated with struct types behave like resources +module 0x1.M1 { + struct MyResource { b: bool } + struct S { t: T } + + // verifer should reject; didn't move resource; + public p(s: Self.S) { + label b0: + return; + } +} + +//# publish +module 0x1.M2 { + struct MyResource { b: bool } + struct S { t: T } + + // verifier should reject; drops s2 on the floor + public p(s1: Self.S, s2: Self.S): Self.S { + label b0: + s1 = move(s2); + return move(s1); + } +} + +//# publish +module 0x1.M3 { + struct MyResource { b: bool } + struct S { t: T } + + // verifier should reject; copies s + public p(s: &Self.S): Self.S { + label b0: + return *move(s); + } +} + +//# publish +module 0x1.M4 { + struct MyResource { b: bool } + struct S { t: T } + + // verifier should reject; drops s1 on the floor + public p(s1: &mut Self.S, s2: Self.S) { + label b0: + *move(s1) = move(s2); + return; + } +} + +//# publish +module 0x1.M5 { + struct MyResource { b: bool } + struct S { t: T } + + // verifier should reject; copies s + public p(s: Self.S): Self.S * Self.S { + label b0: + return (copy(s), move(s)); + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/type_error_after_branch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/type_error_after_branch.exp new file mode 100644 index 000000000..f06938b6a --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/type_error_after_branch.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'run'. lines 1-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 8)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/type_error_after_branch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/type_error_after_branch.mvir new file mode 100644 index 000000000..d38188b4f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/type_error_after_branch.mvir @@ -0,0 +1,19 @@ +//# run +module 0x42.m { + + +entry foo(b: bool) { + let x: u64; +label b0: + jump_if (move(b)) b2; +label b1: + x = 3; + jump b3; +label b2: + x = 2; +label b3: + x = true; // type error here + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.mvir new file mode 100644 index 000000000..552d9d15e --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_resource.mvir @@ -0,0 +1,51 @@ +//# publish +module 0x1.Test { + struct X { b: bool } + struct T { i: u64, x: Self.X, b: bool } + + public new_x(): Self.X { + label b0: + return X { b: true }; + } + + public new_t(x: Self.X): Self.T { + label b0: + return T { i: 0, x: move(x), b: false }; + } + + public destroy_x(x: Self.X) { + let b: bool; + label b0: + X { b } = move(x); + return; + } + + // can unpack a resource and return it + public destroy_t(t: Self.T): u64 * Self.X * bool { + let i: u64; + let x: Self.X; + let flag: bool; + label b0: + T { i, x, b: flag } = move(t); + return move(i), move(x), move(flag); + } + +} + +//# run +module 0x42.m { +import 0x1.Test; + +entry foo() { + let x: Test.X; + let i: u64; + let t: Test.T; + let b: bool; +label b0: + x = Test.new_x(); + t = Test.new_t(move(x)); + i, x, b = Test.destroy_t(move(t)); + Test.destroy_x(move(x)); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.exp new file mode 100644 index 000000000..776bf6054 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-19: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000001::Test'. Got VMError: { + major_status: UNPACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x1::Test, + indices: [(FunctionDefinition, 1)], + offsets: [(FunctionDefinitionIndex(1), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.mvir new file mode 100644 index 000000000..7f64ff169 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unpack_wrong_type.mvir @@ -0,0 +1,19 @@ +//# publish +module 0x1.Test { + struct X { b: bool } + struct T { b: bool } + + public new_t(): Self.T { + label b0: + return T { b: true }; + } + + public destroy_t(t: Self.T) { + let b: bool; + label b0: + // wrong struct in unpack + X { b } = move(t); + return; + } + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.exp new file mode 100644 index 000000000..5d92c423f --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.exp @@ -0,0 +1 @@ +processed 2 tasks diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.mvir new file mode 100644 index 000000000..0cd8850fe --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate.mvir @@ -0,0 +1,29 @@ +//# publish +module 0x42.Test { + struct T has drop {fint: u64, fv: bool} + + public t1(fint: u64, fv: bool): Self.T { + label b0: + return T{fint: move(fint), fv: move(fv)}; + } + + public t2(fint: u64): Self.T { + label b0: + return T{fint: move(fint), fv: false}; + } +} + +//# run + +module 0x42.m { +import 0x42.Test; + +entry foo() { + let t1: Test.T; + let t2: Test.T; +label b0: + t1 = Test.t1(0, false); + t2 = Test.t2(0); + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp new file mode 100644 index 000000000..6603cc326 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.exp @@ -0,0 +1,10 @@ +processed 1 task + +task 0 'publish'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::Test'. Got VMError: { + major_status: PACK_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::Test, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.mvir new file mode 100644 index 000000000..9e987f11c --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unrestricted_instantiate_bad_type.mvir @@ -0,0 +1,10 @@ +//# publish +module 0x42.Test { + struct T{fint: u64} + + public t1(): Self.T { + label b0: + // arg type mismatch + return T{fint: false}; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.exp new file mode 100644 index 000000000..df341dbc4 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.exp @@ -0,0 +1,10 @@ +processed 2 tasks + +task 1 'run'. lines 18-33: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: UNSAFE_RET_UNUSED_VALUES_WITHOUT_DROP, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.mvir new file mode 100644 index 000000000..594869d25 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/unused_resource_holder.mvir @@ -0,0 +1,33 @@ +//# publish + +module 0x42.A { + struct Coin has store { value: u64 } + struct T { g: Self.Coin } + + public zero(): Self.Coin { + label b0: + return Coin { value: 0 }; + } + public new(g: Self.Coin): Self.T { + label b0: + return T {g: move(g)}; + } + +} + +//# run +module 0x42.m { + +import 0x42.A; + +entry foo() { + let zero_resource: A.Coin; + let s: A.T; +label b0: + zero_resource = A.zero(); + // unused resources + s = A.new(move(zero_resource)); + + return; +} +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_ops_type_mismatch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_ops_type_mismatch.exp new file mode 100644 index 000000000..d2d0379f1 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_ops_type_mismatch.exp @@ -0,0 +1,73 @@ +processed 8 tasks + +task 0 'run'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'run'. lines 12-25: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 2 'run'. lines 26-41: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} + +task 3 'run'. lines 42-58: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 8)], +} + +task 4 'run'. lines 59-75: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 6)], +} + +task 5 'run'. lines 76-95: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: STLOC_TYPE_MISMATCH_ERROR, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 6 'run'. lines 96-107: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 7 'run'. lines 108-121: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 5)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_ops_type_mismatch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_ops_type_mismatch.mvir new file mode 100644 index 000000000..871f9cf18 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_ops_type_mismatch.mvir @@ -0,0 +1,121 @@ +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + v = vec_pack_0(); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let v_mut: &mut vector; +label b0: + v = vec_pack_0(); + v_mut = &mut v; + + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let v_imm: &vector; + let v_len: u8; +label b0: + v = vec_pack_0(); + v_imm = &v; + v_len = vec_len(move(v_imm)); + + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let v_mut: &mut vector; + let e: u64; +label b0: + e = 0; + v = vec_pack_0(); + v_mut = &mut v; + vec_push_back(move(v_mut), move(e)); + + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let v_mut: &mut vector; + let e: u64; +label b0: + v = vec_pack_0(); + v_mut = &mut v; + vec_push_back(copy(v_mut), 0); + + e = vec_pop_back(move(v_mut)); + return; +} + +} +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let v_mut: &mut vector; + let i1: u8; + let i2: u128; +label b0: + i1 = 0; + i2 = 1; + v = vec_pack_0(); + v_mut = &mut v; + vec_swap(move(v_mut), move(i1), move(i2)); + + return; +} + +} +// push int on the stack, then try to pack into vector of the wrong type +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + v = vec_pack_1(28u8); + return; +} + +} +// create vector, try to unpack into different type +//# run +module 0x42.m { + +entry foo() { + let v: vector; + let x: bool; + let y: bool; +label b0: + v = vec_pack_2(1u8, 0u8); + x, y = vec_unpack_2(move(v)); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_pack_mismatch.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_pack_mismatch.exp new file mode 100644 index 000000000..f17f2c02b --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_pack_mismatch.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'run'. lines 1-13: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 1)], +} + +task 1 'run'. lines 15-29: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 2)], +} + +task 2 'run'. lines 31-42: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 3)], +} + +task 3 'run'. lines 44-56: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::m'. Got VMError: { + major_status: TYPE_MISMATCH, + sub_status: None, + location: 0x42::m, + indices: [(FunctionDefinition, 0)], + offsets: [(FunctionDefinitionIndex(0), 4)], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_pack_mismatch.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_pack_mismatch.mvir new file mode 100644 index 000000000..ff593222d --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_pack_mismatch.mvir @@ -0,0 +1,56 @@ +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + (1); // 0 + vec_pack_1(); // 1 + v = (); // 2 + return; // 3 +} + +} + +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + (0); // 0 + (false); // 1 + vec_pack_2(); // 2 + v = (); // 3 + return; // 4 + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + (1u8, false, 2u8); + v = vec_pack_3(); + return; +} + +} + +//# run +module 0x42.m { + +entry foo() { + let v: vector; +label b0: + (false, 0, 0, 0); + v = vec_pack_3(); + _ = (); + return; +} + +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.exp new file mode 100644 index 000000000..1417dd426 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.exp @@ -0,0 +1,28 @@ +processed 3 tasks + +task 0 'publish'. lines 1-10: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M1, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 1 'publish'. lines 12-21: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M2, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 2 'publish'. lines 23-32: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M3, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.mvir new file mode 100644 index 000000000..4568022f9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param.mvir @@ -0,0 +1,32 @@ +//# publish +module 0x42.M1 { + struct S { t: T } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(v: vector>): vector> { + label b0: + return move(v); + } +} + +//# publish +module 0x42.M2 { + struct S { t: T } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(v: &vector>) { + label b0: + return; + } +} + +//# publish +module 0x42.M3 { + struct S { t: T } + + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(v: &mut vector>) { + label b0: + return; + } +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param_exploits.exp b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param_exploits.exp new file mode 100644 index 000000000..394bd4191 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param_exploits.exp @@ -0,0 +1,37 @@ +processed 4 tasks + +task 0 'publish'. lines 1-11: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M1'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M1, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 1 'publish'. lines 13-22: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M2'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M2, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 2 'publish'. lines 24-40: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M3'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M3, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} + +task 3 'publish'. lines 42-58: +Error: Unable to publish module '0000000000000000000000000000000000000000000000000000000000000042::M4'. Got VMError: { + major_status: CONSTRAINT_NOT_SATISFIED, + sub_status: None, + location: 0x42::M4, + indices: [(Signature, 0), (FunctionHandle, 0)], + offsets: [], +} diff --git a/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param_exploits.mvir b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param_exploits.mvir new file mode 100644 index 000000000..85de858a9 --- /dev/null +++ b/vendors/move/crates/bytecode-verifier-transactional-tests/tests/type_safety/vector_type_param_exploits.mvir @@ -0,0 +1,58 @@ +//# publish +module 0x42.M1 { + struct S has copy, drop { t: T } + + // it would be bad if this worked because T could be (e.g.) a coin + // should get flagged w/ constraint not satisfied--T does not have copy + public bad_sig(v: vector>): vector> { + label b0: + return copy(v); + } +} + +//# publish +module 0x42.M2 { + struct S has drop { t: T } + + // it would be bad if this worked because T could be (e.g.) a hot potato + public bad_sig(v: vector>) { + label b0: + return; + } +} + +//# publish +module 0x42.M3 { + struct S { t: T } + + public bad_sig(s: vector>) { // should get flagged w/ constraint not satisfied + label b0: + return; + } + + public call(): vector> { + let x: vector>; + label b0: + x = vec_pack_0>(); + Self.bad_sig(&x); + return move(x); + } +} + +//# publish +module 0x42.M4 { + struct S { t: T } + + public bad_sig(s: vector>) { // should get flagged w/ constraint not satisfied + label b0: + return; + } + + public call(): vector> { + let x: vector>; + label b0: + x = vec_pack_0>(); + Self.bad_sig(&x); + return move(x); + } +} diff --git a/vendors/move/crates/changes/1-friend-visibility.md b/vendors/move/crates/changes/1-friend-visibility.md new file mode 100644 index 000000000..4ce2dfa3e --- /dev/null +++ b/vendors/move/crates/changes/1-friend-visibility.md @@ -0,0 +1,195 @@ +# Friend Visibility + +* Status: Implemented in Move 1.2 + +## Introduction + +Friend visibility is a new feature in Move version 1.2 to give more control about where a function can be used. Previously a function had either public or private visibility, where a public function is accessible anywhere but a private function can be called only from within the module where it is defined. Friend-visible functions can be called only from explicitly allowed modules. + +## Motivations + +### Overly Permissive Function Visibility Model + +The simple public/private visibility scheme required using public visibility for “limited-access” functions, i.e., functions that: + +* are designed to have limited access by a known and specific set of modules only (i.e., an allowlist), and +* should not be accessed by any other modules outside this specific allowlist. + +Take all the `initialize` functions in the Diem framework as an example. In theory, the `initialize` functions should only be used by the `Genesis` module and never be exposed to any other modules nor scripts. However, due to the limitation in the current visibility model, these `initialize` functions have to be made `public` (in order for the `Genesis` module to call them) and both runtime capability checks and static verification are enforced to make sure that these functions will abort if not called from a genesis state. + +### Inflexibility in Future Module Updates + +Public functions have very restricted updating rules: a public function can never be deleted or renamed, and its function signature can never be altered. The rationale behind this restriction is that a public function is a contract made to the whole world and once the contract is made, the API should not be easily altered, as altering the API might break code that tries to invoke the public function. The owner of the public function has no control on who can invoke the function. In fact, knowing all the call sites requires a global scan of all code published in storage, which is not always possible nor scalable in a blockchain network with an open-publishing model. + +In contrast, a friend function is only a contract made to the friends of a module, and furthermore, the module owner controls the membership of the friend list. That is, the module owner has complete knowledge of which modules may access a friend function. As a result, it is much easier to update a friend function because only the modules in the friend list needs to be coordinated for the change. This is especially true when a friend function and all its friend modules are maintained by the same owner. + +### Simplification Opportunities for Specification and Verification + +Friend visibility can help simplify specification writing and verification with the Move prover. For example, given a friend function and its host module’s friend list, we can easily and exhaustively find all callsites of the friend function. With this information, we could, as an option, completely skip the specification of a friend function and inline the implementation into the caller. This may lead to further simplification in the verification techniques and allows stronger properties to be proved. In contrast, for a public function, it is necessary to write complete and accurate specifications for the function. + +## Description + +Friend visibility expands the set of possible visibility levels: + +* private (no modifier) +* `public(friend)` +* `public(script)`, and +* `public`. + +These respectively correspond to `Private`, `Friend`, `Script`, and `Public` in the Move bytecode file format. Script visibility addresses an orthogonal problem in the Diem Framework and more details can be found in the [Script Visibility](2-script-visibility.md) change description. + +Beside the new `public(friend)` modifier, each module is allowed to have a friend list, specifiable as zero or more +`friend ` statements that list the modules trusted by the host module. Modules in the friend list are permitted to call a `public(friend)` function defined in the host module, but a non-friend module is prohibited from accessing a `public(friend)` function. + +### New Visibility Modifier + +`public(friend)` is a new visibility modifier that can be applied to any function definition in a module. A `public(friend)` function can be invoked by any other functions in the same module (say module `M`), or any function defined in one of the modules in the friend list of module `M`. + +Besides this visibility rule, `public(friend)` functions follow the same rules as any other module function, meaning they can invoke other functions in the same module (except `public(script)` functions), create new struct instances, access the global storage (of types declared in that module), etc. + +### Friend List Declarations + +A module can declare other modules as friends via friend declaration statements, in the format of + +* `friend ` — friend declaration using fully qualified module name +* `friend ` — friend declaration using a module name alias, where the module alias is introduced via the `use` statement. + +A module may have multiple friend declarations, and the union of all the friend modules is recorded in the friend list, which is a new section in the bytecode file format. For readability, friend declarations should generally be placed near the beginning of the module definition. Note that Move scripts cannot declare friend modules as the concept of friend functions does not even exist in scripts. + +Friend declarations are subject to the following rules: + +* A module cannot declare itself as a friend. + * e.g., `0x2::M` cannot declare `0x2::M` as a friend. +* Friend modules must be within the same account address. + * e.g., `0x2::M` cannot declare `0x3::N` as a friend. + * Note: this is not a technical requirement but rather a policy decision which may be relaxed later. +* Friends relationships cannot create cyclic module dependencies. + * Cycles are not allowed in the friend relationships. E.g., `0x2::A` friends `0x2::B` friends `0x2::C` friends `0x2::A` is not allowed. + * More generally, declaring a friend module adds a dependency upon the current module to the friend module (because the purpose is for the friend to call functions in the current module). If that friend module is already used, either directly or transitively, a cycle of dependencies would be created. E.g., a cycle would be created if `0x2::A` friends `0x2::B` and `0x2::A` also calls a function `0x2::B::foo().` +* Friends must exist when the module is published. + * e.g., `0x2::M` cannot declare `0x2::X` as a friend if `0x2::X` cannot be resolved by the loader. +* The friend list for a module cannot contain duplicates. + +## Examples + +A typical module with `public(friend)` functions and its friend modules is shown in the following example: + +``` +address 0x2 { + module A { + // friend declaration via fully qualified module name + friend 0x2::B; + + // friend declaration via module alias + use 0x2::C; + friend C; + + public(friend) fun foo() { + // a friend function can call other non-script functions in the same module + i_am_private(); + i_am_public(); + bar(); + } + public(friend) fun bar() {} + + fun i_am_private() { + // other functions in the same module can also call friend functions + bar(); + } + public fun i_am_public() { + // other functions in the same module can also call friend functions + bar(); + } + } + + module B { + use 0x2::A; + + public fun foo() { + // as a friend of 0x2::A, functions in B can call friend functions in A + A::foo(); + } + + public fun bar() { + 0x2::A::bar(); + } + } +} +``` + +## Alternatives + +### Granularity of the Friend List + +* Module-to-Module (adopted) + * Module `B` is a friend of module `A` — any function in module `B` can access any friend function in module `A` + * Modules have been the trust boundary in Move language, as evidenced by: + * the existing visibility model where public and private are defined with regard to the hosting module of a particular function; + * the design of Struct / Resource type where only the module that defines the Struct / Resource may access the internals of the type. + * Therefore, it is more natural for modules to be the trust boundary of friend function accesses as well. + * Another reason is that it resonates with the granularity of the friend feature found in other languages (e.g., C++). +* Module-to-Function + * Module `B` is a friend of function `foo()` — any function in module `B` can call the friend function `foo()` + * This is a more fine-grained version of Module-to-Module friendship declaration and is also found in other languages (e.g., C++ also supports Module-to-Function friendship). The reasons we did not choose this option are mostly 1) it breaks the mental model that modules are the boundaries in Move, and 2) it may lead to the case where a module (e.g., module `A`) is a friend of every friend function and `friend A` needs to be specified repeatedly for each friend function. +* Function-to-Module + * Function `foo()` is a friend of module `A` — function `foo()` can call any friend function in module `A` + * The reason this option is not chosen is because it seems weird to express, as a developer, that we trust function `0x3::B::foo()` but not function `0x3::B::bar()`, especially given that both `bar()` and `foo()` reside in the same module by `0x3::B`. We could not contemplate a valid use case for this scenario. +* Function-to-Function + * Function `foo()` is a friend of function `bar()` — function `foo()` can call friend function `bar()` + * Besides the reason that it feels weird trusting one function in a module but not another (similar to the Function-to-Module option), we feel that this scheme is too fine-grained and would cause inflexibility in development, especially on function name updates. To illustrate, suppose `foo()` is a private function in module `B`, and `bar()` is a friend function in module `A`. This scheme requires that when the private function `foo` is renamed, something in module A needs to be updated as well! Function `foo()` is no longer “private” to module `B` under this scheme. + +### Location of Friend Declarations + +* Callee-side declaration (adopted) + * The code owner who develops the module is responsible for specifying who can be a friend of this module at the time of writing the source code. If later the developers want to add / remove new friends, they can always update the friend list and re-publish the module on-chain (subject to updatability and compatibility checking). + * This is the most natural way of defining the friend list, since the friend list is embedded the same source file as the module source code. Compared with the alternative — caller-side declaration — it is cognitively easier for developers to figure out who may interact with the friend functions and how the friend functions should be hardened by looking within the same file. +* Caller-side declaration + * An alternative thinking is to have the user of a friend function to “request” friendship permission, instead of having the owner of the friend function to “grant” friendship. To illustrate, if module `B` wants to access some friend functions in module `A`, then, the friendship with module `A` will be declared in the source code of module `B` (while the callee-side declaration requires that the friendship is declared in the source code of module `A`). + * A major drawback in this alternative is that the code owner does not have a list of friend relationships if the developers do not actively maintain one. For friend relationships, the source of truth is likely to be stored on-chain either via 1) a VM-updatable section in on-chain module bytecode, or 2) a new `FriendList` entity in users’ accounts. More importantly, by looking at the source code of a module, the developers have no clue who can access the friend function and how the interaction may happen. + +### Publishing Order + +Cross-module references complicate the process for publishing those modules. The issue can be illustrated in the following: + +``` +address 0x2 { + module M { + friend 0x2::N; + public(friend) fun foo() {} + } + module N { + use 0x2::M; + fun bar() { M::foo(); } + } +} +``` + +Suppose we define two modules `M` and `N` like the above: + +* Module `N` depends on `M` because `N` contains `use 0x2::M` +* But, at the same time, module `M` refers to `N` because `M` specifies `friend 0x2::N` + +Now think about how we should publish them on-chain.... + +* With the current one-module-at-a-time publishing model: + * Obviously module `M` has to be published first. Otherwise, publishing module `N` first will make `N::bar()` fail miserably, while publishing `M` first should have no bad effects because no one can call `M::foo()` anyway. + * But, when publishing `M`, the bytecode verifier sees the visibility constraint, and it is a pointer to a nonexistent function `N::bar()`. The bytecode verifier will *not* try to resolve this function handle. It *must* tolerate that this visibility constraint is a forward declaration. + * A risk associated with the above procedure is the possibility of a race condition when publishing module `N`. Suppose both Alice and Eve can publish to `0x2`. When `M` is published, both Alice and Eve see that `M` declares `N` as a friend. Eve may race against Alice to publish module `N` first, with a bad `bar()` function, to exploit the trust the developer of module `M` placed on Alice. + * A solution to this problem is enforcing a safer but more convoluted module publication flow that still uses the one-module-at-a-time publishing model. For the example above, the flow would require three steps: + * publish an empty module `N` as a place holder + * publish module `M` + * publish the updated module `N` that uses the friend function `M` +* With a future multi-signer, multi-module publication model: + * To avoid a convoluted module publishing flow, another solution is to use a multi-signer + multi-module publication model that allows a bundle of modules to be published / updated atomically, even if these modules reside in different user accounts. In the above case, if we could publish `M` and `N` atomically in one transaction, there would be no risk of a race condition and there is no need to go through the three-step module publishing flow. + +### Other Schemes for “Shared” Visibility + +* Address visibility + * Java uses a “package” concept that maps to a given location (namespace) which could roughly be thought of as an address (the address the modules are published under). Addresses in Move could serve the role of “package” in Java. With that approach, we could do something like `public(address)` — or just `internal` — that would allow for cross module visibility, but just under that address. The owner of that address would control all publishing into that address. This kind of visibility would be easy to enforce by a verifier given the address constraints. That is, the target function when linking would have to be in a module published under the same address. + * The problem with this model is that we have no way to control subsequent publishing into that address, which could violate the principle in Move that all bindings are known when one publishes and they cannot be altered. If publishing under the same address gave someone access to the internal state of other modules it would be possible to read and alter state that was originally intended to be private to a group of modules. +* Package visibility + * This is the the .NET CLR model of “internal” visibility, i.e., things that get compiled together can access each other's internal state based merely on the fact that they are compiled together. In Move, “compiled together” really means published together, so a bundle would require a change in publishing (and the module publish transaction) that would have to accept a list of modules rather than a single one. That would give the verifier a chance to control access across modules. That is, cross module calls towards internal visibility would be allowed if the modules are in the same publish unit (bundle). + * However, without some extra information to identify the modules in a bundle, this approach implies that visibility/accessibility cannot be verified after publishing (e.g., while loading). The VM would have to assume that every internal access is good because it has no way to verify it after the publishing time. + * Versioning or upgrades could create problems with this model too, if a version would leave behind some modules that would keep visibility permission but were not intended to. That is something to analyze in more detail and it may or may not be a problem. Essentially the problem is whether verification at publishing time is enough to ensure correctness. It may be argued that the VM knowing the module bundle before and after could be enough to build the dependency graph before and after, and to report errors if any permission inconsistency is detected. + * Alternatively, modules could declare the “bundle” to which they belong. The binary format could have an entry for the set of modules published together, and those would define the scope when checking internal visibility/accessibility. The bundle would still be published together but then the bytecode verifier would have knowledge of which modules to take into account when verifying internal access. + * Friend visibility for selected modules fundamentally provides more fine grained access control than package visibility with bundles of modules. And, since Move does not yet have a concept of multi-module packages, friend visibility is a better option. diff --git a/vendors/move/crates/changes/2-script-visibility.md b/vendors/move/crates/changes/2-script-visibility.md new file mode 100644 index 000000000..afb780fdb --- /dev/null +++ b/vendors/move/crates/changes/2-script-visibility.md @@ -0,0 +1,127 @@ +# Script Visibility + +* Status: Implemented in Move 1.2 + +## Introduction + +Script visibility is a new feature in Move version 1.2 to allow module functions to be safely and directly invoked much like scripts. Previously a function had either public or private visibility, where a public function is accessible anywhere but a private function can be called only from within the module where it is defined. A function with script visibility can be invoked directly, much like scripts, and is restricted to only being callable from scripts or other script visible functions. + +## Motivations + +### Managing the Hash-based Allow-list + +In the Diem Framework, there was a hash-based allowlist of valid scripts that could be sent to the network. If the hash of a script was present in the list, the script could be executed. Otherwise, the transaction was rejected. + +This solution worked but was rather cumbersome, especially if all the hash values change due to something like a new Move bytecode version. In an upgrade scenario, the allowlist would have to be upgraded in the same write-set transaction. While this difficult upgrade path could work, it would not scale well in the future. To the extent possible, Diem should continue to support old transactions, both to ease the upgrade process for clients and also to allow pre-signed transactions that are rarely updated (e.g., for emergency key rotations). The allowlist would then need to include all the old hash values from previous releases, and it would quickly grow in size and become hard to manage. Script visibility solves this problem by including the allowed scripts as part of the Diem Framework instead of tracking their hash values. + +### Diem Framework Updates + +At some time in the future, when Diem allows arbitrary transactions with script-functions, public APIs in the Diem Framework will be extremely difficult to change, but for now, it is still important to evolve the framework with critical changes that are incompatible with scripts from previous versions. This conflicts with the desire to continue supporting transactions from previous releases. With script visibility, the contents of the supported scripts can evolve along with the framework because the Move bytecodes for those scripts are not contained within the transactions, but are instead stored on chain as part of the framework. + +### Meaningless Wrappers + +Many of the scripts we have seen are simple wrappers around a single function call or two. These scripts did not contain any interesting ad-hoc computation (and could not be doing so in the Diem Framework with its allow list). It would be convenient if a module writer could autogenerate scripts for certain functions, or simply mark which functions could be invoked directly, as if they were scripts. + +## Description + +The `script` visibility level solves these problems. In the previous version of Move, functions in a module could be declared as either `public` or private (`Public` or `Private` in the Move bytecode file format). With this change, the possible visibility levels are now: private (no modifier), `public(friend)`, `public(script)`, and `public`. These respectively correspond to `Private`, `Friend`, `Script`, and `Public` in the file format. (See the [Friend Visibility](1-friend-visibility.md) change description for more details on that new feature.) + +A `public(script)` function can only be called from 1) other `public(script)` functions, or 2) from transaction scripts. And, if the function has a signature that meets the necessary restrictions for a script-function, it can be invoked directly by the Move VM as if it was a script. + +### New Visibility Modifier + +`public(script)` is a new visibility modifier that can be applied to any module’s functions. A `public(script)` function can be invoked by any other `public(script)` function (whether or not it is in the same module) or by a script-function. Besides this visibility rule, `public(script)` functions follow the same rules as any other module function, meaning they can invoke private functions, create new struct instances, access global storage (of types declared in that module), etc. + +Unlike script-functions, the signature of `public(script)` functions is not restricted. Any signature that is valid for another module function is a valid signature for a `public(script)` function. But, to be invoked by the Move VM as a script, the `public(script)` function must meet the same restrictions of a script-function. In other words, while every script-function has a restricted signature, the restrictions of a `public(script)` function are checked dynamically when used as an entry point to execution. + +### New VM Entry Point + +A new entry point `execute_script_function` is added to the VM to allow the invocation of a `public(script)` function in published modules. The entry point takes the following signature: + +``` +fn execute_script_function( + &self, + module: &ModuleId, + function_name: &IdentStr, + ty_args: Vec, + args: Vec>, + senders: Vec, + data_store: &mut impl DataStore, + cost_strategy: &mut CostStrategy, + log_context: &impl LogContext, +) -> VMResult<()> +``` + +The entry point is designed to be similar to the existing `execute_script` entry point, with only one change: + +* argument `script: Vec` (i.e., a serialized script in raw bytes) is replaced by a pair of `module: &ModuleId` and `function_name: &IdentStr` that uniquely identifies a `public(script)` function in a published module (assuming the function exists). + +The VM will reject the execution with proper status codes in the following situations: + +* the `module` or `function_name` does not exist +* the function being pointed to is not a `public(script)` function +* the signature of the `public(script)` function does not pass the script signature check: + * All `signer` arguments must occur before non-`signer` arguments + * The function does not return any value + * Each non-`signer` type in function type arguments is a valid type for a constant + * Ostensibly, the type has the `copy` ability and is not a struct + * Each type in the function type variables is closed, i.e., does not refer to other type variables +* the `senders`, `args`, or `ty_args` do not match the declared function signature. + +## Examples + +The feature is best used when you have a script that is a simple wrapper around a function in a module: + +``` +script { + fun call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) + } +} +``` + +Changing the module’s function from `public` to `public(script)` will remove the need for this simple wrapper script: + +``` +address 0x42 { +module M { + ... + // Replace previous "public" visibility... + public(script) fun foo(account: signer, amount: u64) { + ... + } +} +} +``` + +However, keep in mind that the function can now only be called from other `public(script)` functions or script-functions. + +``` +address 0x43 { +module Other { + fun private_call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) // ERROR Now invalid + } + + public fun public_call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) // ERROR Now invalid + } + + public(script) fun script_call_foo(account: signer, amount: u64) { + 0x42::M::foo(account, amount) // Still a valid call + } +} +} + +script { + fun still_valid(account: signer) { + 0x42::M::foo(account, 0) // Still a valid call + } +} +``` + +## Alternatives + +We did not see many other options that would address the script versioning problem caused by the hash-based allowlist. Converting transaction scripts into `public(script)` functions that are published and change alongside the corresponding module was the most straightforward solution. + +For the issue of meaningless wrappers alone, we considered compiler support to have scripts auto-generated. The generation by the compiler would be relatively simple, but it is unnecessary in the presence of `public(script)` functions. diff --git a/vendors/move/crates/changes/3-abilities.md b/vendors/move/crates/changes/3-abilities.md new file mode 100644 index 000000000..ce1f08efc --- /dev/null +++ b/vendors/move/crates/changes/3-abilities.md @@ -0,0 +1,439 @@ +# Abilities + +* Status: Implemented in Move 1.2 + +## Introduction + +Abilities are a new feature in Move version 1.2 to give more control over what actions are permissible for values of a given type. Previously in Move’s type system, there were copyable values and `resource` values. In this old system, copyable values were unrestricted, but resource values could not be copied and had to be used. With abilities, Move’s type system grants more fine grained control, allowing types to specifically allow certain operations for their values that were previously implicitly allowed/denied depending on the “kind” (copyable or resource). + +## Motivations + +Move’s kind system (copyable vs. resource structs) has been great, but it is not expressive enough for certain applications. Resource types are very powerful, but the system bundles up a lot of behavior into one kind, which does not always meet application needs. In the Diem Framework, there has been a need for a “hot potato” type for capabilities—that is some type that cannot be copied or dropped (like a resource), but cannot be stored in global storage. It is then a “hot potato” since you must keep passing it around and it must be consumed before the transaction completes. A type with these restrictions would allow the Move prover to verify the usage of these specific capabilities. + +Extending the kind system just to handle this “hot potato” example is likely not the best future-proof solution. A more granular system can give programmers more control to implement not only “hot potato” types but also serve yet unknown needs. As such, we want the new system to be flexible enough to be extended in the future without requiring another large refactoring of the type system. + +## Description + +The kinds copyable and resource are replaced by four new *abilities*. These abilities gate access to various bytecode instructions. In order for a value to be used with the bytecode instruction, it must have the ability required (if one is required at all—not every instruction is gated by an ability). + +### The Abilities + +The four added abilities are `copy`, `drop`, `store`, and `key`. Broken down in detail: + +* `copy` + * Allows values of types with this ability to be copied + * Gates: `CopyLoc` and `ReadRef` + * If a value has `copy`, all values reachable inside of that value have `copy`. +* `drop` + * Allows values of types with this ability to be popped/dropped. + * Ownership does not *have* to be transferred + * Gates: `Pop`, `WriteRef`, `StLoc`, `Eq` and `Neq` + * Values left in local variables must have `drop` when the function returns with `Ret` + * If a value has `drop`, all values reachable inside of that value have `drop`. +* `store` + * Allows values of types with this ability to exist inside a struct in global storage + * But not necessarily as a top-level value in global storage + * This is the only ability currently that is not directly checked by an operation. But it is indirectly checked when `key` is checked + * If a value has `store`, all values reachable inside of that value have `store`. +* `key` + * Allows the type to serve as a key for global storage operations + * Letting values of types with this ability exist at the top-level of global storage + * Gates: `MoveTo`, `MoveFrom`, `BorrowGlobal`, `BorrowGlobalMut`, and `Exists` + * If a value has `key`, all values reachable inside of that value have `store`. + +### Primitive Types + +Most primitive types all have `copy`, `drop`, and `store` with the exception of `signer`. + +* `bool`, `u8`, `u64`, `u128`, and `address` all have `copy`, `drop`, and `store`. +* `signer` has `drop` + * Cannot be copied and cannot be put into global storage +* `vector` may have `copy`, `drop`, and `store` depending on the abilities of `T`. + * See [Conditional Abilities with Generic Types](#Conditional-Abilities-with-Generic-Types) for more details. +* Immutable references `&` and mutable references `&mut` both have `copy` and `drop`. + * This refers to copying and dropping the reference itself, not what they refer to. + * References cannot appear in global storage, hence they do not have `store`. + +### Annotating Structs + +To declare that a `struct` has an ability, it is declared with `has ` after the struct name but before the fields. For example: + +``` +struct Ignorable has drop { f: u64 } +struct Pair has copy, drop, store { x: u64, y: u64 } +``` + +In this case `Ignorable` has the `drop` ability, and `Pair` has `copy`, `drop`, and `store`. + +When declaring a struct’s abilities, certain requirements are placed on the fields. All fields must satisfy these constraints. These rules are necessary so that structs satisfy the reachability rules for abilities given above. If a struct is declared with the ability... + +* `copy`, all fields must have `copy` +* `drop`, all fields must have `drop` +* `store`, all fields must have `store` +* `key`, all fields must have `store` + * `key` is the only ability currently that doesn’t require itself. + +For example: + +``` +// A struct without any abilities +struct NoAbilities {} + +struct WantsCopy has copy { + f: NoAbilities, // ERROR 'NoAbilities' does not have 'copy' +} +``` + +and similarly: + +``` +// A struct without any abilities +struct NoAbilities {} + +struct MyResource has key { + f: NoAbilities, // Error 'NoAbilities' does not have 'store' +} +``` + +### Basic Examples + +**Copy** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } + +fun example(x: u64, s: S) { + let x2 = copy x; // Valid, 'u64' has 'copy' + let s2 = copy s; // Valid, 'S' has 'copy' +} + +fun invalid(account: signer, n: NoAbilities) { + let a2 = copy account; // Invalid, 'signer' does not have 'copy' + let n2 = copy n; // Invalid, 'NoAbilities' does not have 'drop' +} +``` + +**Drop** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } + +fun unused() { + true; // Valid, 'bool' has 'drop' + S { f: false }; // Valid, 'S' has 'drop' +} + +fun left_in_local(account: signer): u64 { + let b = true; + let s = S { f: false }; + // Valid return: 'account', 'b', and 's' have values + // but 'signer', 'bool', and 'S' have 'drop' + 0 +} + +fun invalid_unused() { + NoAbilities {}; // Invalid, Cannot ignore 'NoAbilities' without 'drop' +} + +fun invalid_left_in_local(): u64 { + let n = NoAbilities{}; + // Invalid return: 'n' has a value and 'NoAbilities' does not have 'drop' + 0 + +} +``` + +**Store** + +``` +// 'MyInnerResource' is declared with 'store' so all fields need 'store' +struct MyInnerResource has store { + yes: u64, // Valid, 'u64' has 'store' + // no: signer, Invalid, 'signer' does not have 'store' +} + +// 'MyResource' is declared with 'key' so all fields need 'store' +struct MyResource has key { + yes: u64, // Valid, 'u64' has 'store' + inner: MyInnerResource, // Valid, 'MyInnerResource' has 'store' + // no: signer, Invalid, 'signer' does not have 'store' +} +``` + +**Key** + +``` +struct NoAbilities {} +struct MyResource has key { f: u64 } + +fun valid(account: &signer) acquires MyResource { + let addr = signer::address_of(account); + let has_resource = exists(addr); // Valid, 'MyResource' has 'key' + if (!has_resource) { + move_to(account, MyResource { f: 0 }) // Valid, 'MyResource' has 'key' + }; + let r = borrow_global_mut(addr) // Valid, 'MyResource' has 'key' + r.f = r.f + 1; +} + +fun invalid(account: &signer) { + let has_it = exists(addr); // Invalid, 'NoAbilities' does not have 'key' + let NoAbilities {} = move_from(addr); // Invalid, does not have 'key' + move_to(account, NoAbilities {}); // Invalid, 'NoAbilities' does not have 'key' + borrow_global(addr); // Invalid, 'NoAbilities' does not have 'key' +} +``` + +### Constraining Generics + +Abilities can used to constrain generics, meaning that only types with that ability can instantiate that type parameter. This can be used on both function and struct type parameters: + +``` +fun foo(x: T): (T, T) { (copy x, x) } +struct CopyCup has copy { item: T } +``` + +Type parameters can have more than one constraint, signified with `+` + +``` +fun bar(x: T): T { copy x } +struct AllCup has copy, drop, store, key { item: T } +``` + +### Conditional Abilities with Generic Types + +When abilities are annotated on a generic type, not all instances of that type are guaranteed to have that ability. Consider this struct declaration: + +``` +struct Cup has copy, drop, store, key { item: T } +``` + +The type parameter `T` is assumed to be used inside of the struct, so the abilities are only granted if the type parameters meet the requirements described above for fields. That means: + +* `Cup` has the ability `copy` only if `T` has `copy`. +* It has `drop` only if `T` has `drop`. +* It has `store` only if `T` has `store`. +* It has `key` only if `T` has `store`. + +This behavior might be a bit confusing at first, but it is extremely useful for collection-like types. Consider `vector`: we could consider it to have the following type declaration: + +``` +vector has copy, drop, store; +``` + +With this, you can copy a `vector` value only if the inner elements can be copied. You can ignore a `vector` value only if the inner elements can be ignored/dropped. And, a `vector` can be in global storage only if the inner elements can be in global storage. + +### More Examples + +**Conditional Copy** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun example(c_x: Cup, c_s: Cup) { + // Valid, 'Cup' has 'copy' because 'u64' has 'copy' + let c_x2 = copy c_x; + // Valid, 'Cup' has 'drop' because 'S' has 'drop' + let c_s2 = copy c_s; +} + +fun invalid(c_account: Cup, c_n: Cup) { + // Invalid, 'Cup' does not have 'copy'. + // Even though 'Cup' was declared with copy, the instance does not have 'copy' + // because 'signer' does not have 'copy' + let c_account2 = copy c_account; + // Invalid, 'Cup' does not have 'drop' + // because 'NoAbilities' does not have 'drop' + let c_n2 = copy c_n; +} +``` + +**Drop** + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun unused() { + Cup { item: true }; // Valid, 'Cup' has 'drop' + Cup { item: S { f: false }}; // Valid, 'Cup' has 'drop' +} + +fun left_in_local(c_account: Cup): u64 { + let c_b = Cup { item: true }; + let c_s = Cup { item: S { f: false }}; + // Valid return: 'c_account', 'c_b', and 'c_s' have values + // but 'Cup', 'Cup', and 'Cup' have 'drop' + 0 +} + +fun invalid_unused() { + // Invalid, Cannot ignore 'Cup' because it does not have 'drop'. + // Even though 'Cup' was declared with 'drop', the instance does not have 'drop' + // because 'NoAbilities' does not have 'drop' + Cup { item: NoAbilities {}}; +} + +fun invalid_left_in_local(): u64 { + let n = Cup { item: NoAbilities {}}; + // Invalid return: 'c_n' has a value + // and 'Cup' does not have 'drop' + 0 + +} +``` + +**Store** + +``` +struct Cup has copy, drop, store { item: T } + +// 'MyInnerResource' is declared with 'store' so all fields need 'store' +struct MyInnerResource has store { + yes: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} + +// 'MyResource' is declared with 'key' so all fields need 'store' +struct MyResource has key { + yes: Cup, // Valid, 'Cup' has 'store' + inner: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} +``` + +**Key** + +``` +struct NoAbilities {} +struct MyResource has key { f: T } + +fun valid(account: &signer) acquires MyResource { + let addr = signer::address_of(account); + // Valid, 'MyResource' has 'key' + let has_resource = exists>(addr); + if (!has_resource) { + // Valid, 'MyResource' has 'key' + move_to(account, MyResource { f: 0 }) + }; + // Valid, 'MyResource' has 'key' + let r = borrow_global_mut>(addr) + r.f = r.f + 1; +} + +fun invalid(account: &signer) { + // Invalid, 'MyResource' does not have 'key' + let has_it = exists>(addr); + // Invalid, 'MyResource' does not have 'key' + let NoAbilities {} = move_from(addr); + // Invalid, 'MyResource' does not have 'key' + move_to(account, NoAbilities {}); + // Invalid, 'MyResource' does not have 'key' + borrow_global(addr); +} +``` + +### Backwards Compatibility + +The new ability system is backwards compatible with the kind system in nearly all cases. At the bytecode level, old modules and scripts with kinds can be loaded as if they were written with abilities. + +For any struct: + +* If it was declared as a “copyable”, non-`resource` struct, the struct will be given the abilities `copy`, `drop`, and `store`. +* If it was declared as a `resource`, the struct will be given the abilities `store` and `key`. +* For type parameters: + * `copyable` becomes `copy + drop` + * `resource` becomes `key` + * `store` is not given as it is not needed in the constraint position. Any usage will still work. + +For any function: + +* For type parameters: + * `copyable` becomes `copy + drop + store` + * `resource` becomes `key + drop` + * `store` is needed as it is not simple to determine if the type parameter will be used with global storage operations. + +Putting these rules together, the old code + +``` +struct S {} +resource struct R {} + +fun foo() {} +``` + +will be loaded as if it was written as: + +``` +struct S has copy, drop, store {} +struct R {} + +fun foo() {} +``` + +This leads to one spot where there is a breaking change, namely any function instantiated with `signer` as a type parameter will not now load because the type parameter will have the `store` constraint—all old function type parameters are given the `store` constraint—but `signer` does not have `store`. Given the restricted usage of `signer`, this is likely an extreme edge case, and we do not foresee it being an issue in practice for any project. + +## Alternatives + +### Extending the Kind System + +For the main motivating example for this change, it was considered to add a “hot potato” kind to the system. +In the kind system there was: + +* `Copyable` which corresponds to `copy + drop + store`, +* `Resource` which corresponds to `key + store` +* `All` which sometimes corresponds to `store` and sometimes to no-ability + +Often this was viewed with a sub-kinding system where `Copyable <: All` and `Resource <: All`. Adding a `HotPotato` kind to this system would be bit tricky, possibly giving a hierarchy of `Copyable <: All` and `Resource <: HotPotato <: All`. But, this could become a mess if: + +* There needed to be an `AllWithStore` kind, giving `Copyable <: AllWithStore <: All` and `Resource <: AllWithStore <: All` and `Resource <: HotPotato <: All`. +* If any other kind was added, the complexity could quickly explode. + +The complexity around this sub-kinding approach led to the more granular approach described above with abilities. We were particularly worried about needing another kind in a year or two and having the whole thing collapse. With abilities, we can easily add new ones over time if needed. + +### Explicit Conditional Abilities + +The current rules around generics being conditional for generic types might be potentially confusing, especially given the keyword `has`. For instance: + +``` +struct Cup has copy, drop, store { item: T } +``` + +Despite effectively saying “has copy” and “has drop” and “has store”, `Cup` may or may not have the ability depending on what `T` is. This might be rather confusing. It was considered then that for generic types you would write: + +``` +struct Cup has ?copy, ?drop, ?store { item: T } +``` + +This would mean exactly what it means today, where it may or may not have the ability depending on `T` and then using `has` without the question mark `?` + +``` +struct Ex has copy {} +``` + +would be equivalent to: + +``` +struct Ex has ?copy {} +``` + +The potential problem then comes in that there are a lot of combinations that are meaningless. So, in many cases the compiler would yell at you that there is really just one valid choice. + +* `struct Ex has copy` is sort of redundant and could just be `struct Ex has copy`. +* For a non-generic type, `struct Ex has ?copy` is meaningless in some way, as every instance has the ability, and it is the same as `struct Ex has copy`. + +In short, having the option to have the question mark `?` caused there to be more cases and possibly more confusion. Furthermore this system was not more expressive, as a programmer could always annotate the generic `struct Cup has copy`, this would force every instance to have `copy` in a more explicit manner. In short, just having one option and one rule that might be a bit more confusing in the way it reads at first, but reduces the amount of complexity to consider when declaring a new struct. + +### Alternative Names + +Many different names were considered for all aspects of the abilities system. + +* For the name “ability” itself, “kinds”, “traits”, “type classes”, and “interfaces” were all considered. But these items used in other programming languages are usually used to describe programmer-defined items. There is no way for programmers to define their own abilities. Additionally, abilities do not give anything that looks like dynamic dispatch. So, while those other names might be more familiar, we worried they would be too misleading. +* `copyable` and `dropable` and `storable` were all considered, but they felt too wordy. Shorter names felt more appropriate. +* `mustuse` or `mustmove` were considered for `drop`, but again, the more concise name felt better even if the others were more informative. +* `resource` was considered instead of `key`. The `key` ability is very similar to the `resource` keyword in many cases, but it felt very weird that something like a `Coin` which might have been `resource struct Coin` in the old system, would not be `struct Coin has store` and would not be a “resource”. Thus we are saving the word “resource” to be used in documentation for any time that does not have `copy` or `drop`. diff --git a/vendors/move/crates/changes/4-unit-testing.md b/vendors/move/crates/changes/4-unit-testing.md new file mode 100644 index 000000000..464d1ce30 --- /dev/null +++ b/vendors/move/crates/changes/4-unit-testing.md @@ -0,0 +1,345 @@ +# Unit Testing + +* Status: Implemented in Move 1.3 + +## Introduction + +Unit testing is a new feature in Move version 1.3 to allow Move programmers to more easily and concisely test individual functions and features. Previously, the only way to test Move code was using more heavyweight expected-value and transaction-based tests via the Move CLI and Diem functional test framework. Additionally, it was hard — if not impossible — to set up arbitrary state for testing, to test non-public functions, and to have test-only dependencies, functions, and datatypes. With the new Move unit testing feature these are all possible and easy to express. + +## Motivation + +Being able to test code thoroughly is an essential ability when developing Move code. However, without a unit testing framework for Move, achieving high test coverage for both public and private functions that is clear and easily maintainable is a challenging task. + +Move unit tests are written in the module whose functionality they are testing. Because of this, unit tests have access to private functions and can freely construct and publish instances of datatypes defined in the module. This allows a more declarative and transparent style of testing as compared to previous options, where complex sequences of transactions could be needed to set up the state in a specific manner to test a particular code path in a function. + +Sometimes there are cross-module data dependencies, functions, or datatypes that you would like to have for testing purposes only. Move unit tests allow expressing that modules, and module members (`use`s, functions, and datatypes) are for testing purposes only. When members are annotated as `#[test_only]` or `#[test]` they will not appear in the compiled bytecode outside of testing. For those familiar with Rust, this is similar to `#[cfg(test)]` and `#[test]` respectively. + +## Description + +Unit testing for Move adds three new annotations to the Move source language: + +* `#[test]` +* `#[test_only]`, and +* `#[expected_failure]`. + +They respectively mark a function as a test, mark a module or module member (`use`, function, or struct) as code to be included for testing only, and mark that a test is expected to fail (abort). These annotations can be placed on a function with any visibility. Whenever any module or module member is annotated as `#[test_only]` or `#[test]`, it will not be included in the compiled bytecode unless it is compiled for testing. + + +### Testing Annotations: Their Meaning and Usage + +Both the `#[test]` and `#[expected_failure]` annotations can be used either with or without arguments. + +Without arguments, the `#[test]` annotation can only be placed on a function with no parameters. This annotation simply marks this function as a test to be run by the unit testing harness. + +``` +#[test] // OK +fun this_is_a_test() { ... } + +#[test] // Will fail to compile since the test takes an argument +fun this_is_not_correct(arg: signer) { ... } +``` + +A test can also be annotated as an `#[expected_failure]`. This annotation marks that the annotated test should abort — however the exact abort code is not checked. The test will be marked as failing only if the test fails with a non-abort error, or does not abort. Only functions that have the `#[test]` annotation can also be annotated as an #`[expected_failure]`. + +``` +#[test] +#[expected_failure] +public fun this_test_should_abort_and_pass() { abort 1 } + +#[test, expected_failure] // Can have multiple in one attribute. This test will pass. +public(script) fun this_other_test_should_abort_and_pass() { abort 1 } +``` + +With arguments, a test annotation takes the form `#[test( =
, ..., =
)]`. If a function is annotated in such a manner, the function's parameters must be a permutation of the parameters <`param_name_1>, ..., `, i.e., the order of these parameters as they occur in the function and their order in the test annotation do not have to be the same, but they must be able to be matched up with each other by name. + +Only parameters with a type of `signer` are supported as test parameters. If a non-`signer` parameter is supplied, the test will result in an error when run. + +``` +#[test(arg = @0xC0FFEE)] // OK +fun this_is_correct_now(arg: signer) { ... } + +#[test(wrong_arg_name = @0xC0FFEE)] // Not correct: arg name doesn't match +fun this_is_incorrect(arg: signer) { ... } + +#[test(a = @0xC0FFEE, b = @0xCAFE)] // OK. We support multiple signer arguments, but you must always provide a value for that argument +fun this_works(a: signer, b: signer) { ... } + +// somewhere a named address is declared +#[test_only] // test-only named addresses are supported +address TEST_NAMED_ADDR = @0x1; +... +#[test(arg = @TEST_NAMED_ADDR)] // Named addresses are supported! +fun this_is_correct_now(arg: signer) { ... } +``` + +An expected failure annotation can also take the form `#[expected_failure(abort_code = )]`. If a test function is annotated in such a way, the test must abort with an abort code equal to ``. Any other failure or abort code will result in a test failure. + +``` +#[test, expected_failure(abort_code = 1)] // This test will fail +fun this_test_should_abort_and_fail() { abort 0 } + +#[test] +#[expected_failure(abort_code = 0)] // This test will pass +fun this_test_should_abort_and_pass_too() { abort 0 } +``` + +A module and any of its members can be declared as test only. In such a case the item will only be included in the compiled Move bytecode when compiled in test mode. Additionally, when compiled outside of test mode, any non-test `use`s of a `#[test_only]` module will raise an error during compilation. + +``` +#[test_only] // test only attributes can be attached to modules +module ABC { ... } + +#[test_only] // test only attributes can be attached to named addresses +address ADDR = @0x1; + +#[test_only] // .. to uses +use 0x1::SomeOtherModule; + +#[test_only] // .. to structs +struct SomeStruct { ... } + +#[test_only] // .. and functions. Can only be called from test code, but not a test +fun test_only_function(...) { ... } +``` + +### Running Unit Tests + +Unit tests can be compiled and run by the `move-unit-test` crate. It is designed to work out-of-the box, so all you need to start running tests is to pass the files—or directories containing files—that you wish to test (and all dependencies): + +``` +$ cargo run --bin move-unit-test ... +``` + +When running tests, every test will either `PASS`, `FAIL`, or `TIMEOUT`. If a test case fails, the location of the failure along with the function name that caused the failure will be reported if possible. You can see an example of this below. + +A test will be marked as timing out if it exceeds the maximum gas that can be executed for any single test. When a gas table is not provided, each bytecode instruction is assigned a gas cost of 1 unit. This bound can be changed using the options below, and its default value is set to 5000 gas units. Additionally, while the result of a test is always deterministic, tests are run in parallel by default, so the ordering of test results in a test run is non-deterministic unless running with only one thread (see `OPTIONS` below). + +There are also a number of options that can be passed to the unit testing binary to fine-tune testing, and to help debug failing tests. These are: + +``` +FLAGS: + --stackless Use the stackless bytecode interpreter to run the tests and cross check its results with the + execution result from Move VM + -g, --state_on_error Show the storage state at the end of execution of a failing test + -h, --help Prints help information + -l, --list List all tests + -s, --statistics Report test statistics at the end of testing + -V, --version Prints version information + -v, --verbose Verbose mode + +OPTIONS: + -f, --filter A filter string to determine which unit tests to run + -i, --gas_limit Bound the amount of gas used by any one test. [default: 1_000_000] + -t, --threads Number of threads to use for running tests [default: 8] + +ARGS: + ... Source files +``` + +While each of these flags and options are fairly self-explanatory, it is worth mentioning that when filtering tests with the `-f` option, any test whose fully qualified name (i.e., `address::module::function_name`) contains the `` string will be run. + +### Compilation + +You should always use the unit testing framework for unit testing Move code. However, there may be times when you may wish to include test-only code outside of unit testing. In such scenarios Move source code can be compiled with test-code included by passing the `--test` flag to the Move compiler. + +## Examples + +A simple module using some of the unit testing features is shown in the following example: + +``` +// filename: MyModule.move +module 0x1::MyModule { + + struct MyCoin has key { value: u64 } + + public fun make_sure_non_zero_coin(coin: MyCoin): MyCoin { + assert(coin.value > 0, 0); + coin + } + + public fun has_coin(addr: address): bool { + exists(addr) + } + + #[test] + fun make_sure_non_zero_coin_passes() { + let coin = MyCoin { value: 1 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test] + // Or #[expected_failure] if we don't care about the abort code + #[expected_failure(abort_code = 0)] + fun make_sure_zero_coin_fails() { + let coin = MyCoin { value: 0 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test_only] // test only helper function + fun publish_coin(account: &signer) { + move_to(account, MyCoin { value: 1 }) + } + + #[test(a = @0x1, b = @0x2)] + fun test_has_coin(a: signer, b: signer) { + publish_coin(&a); + publish_coin(&b); + assert(has_coin(@0x1), 0); + assert(has_coin(@0x2), 1); + assert(!has_coin(@0x3), 1); + } +} +``` + +### Running Tests + +``` +$ cargo run --bin move-unit-test MyModule.move +Running Move unit tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +[ PASS ] 0x1::MyModule::test_has_coin +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +### Using Test Flags + +#### `-f ` or `--filter ` +This will only run tests whose fully qualified name contains ``. For example if we wanted to only run tests with `"zero_coin"` in their name: + +``` +$ cargo run --bin move-unit-test MyModule.move -f zero_coin +Running Move unit tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +Test result: OK. Total tests: 2; passed: 2; failed: 0 +``` + +#### `-i ` or `--gas_limit ` +This bounds the amount of gas that can be consumed for any one test to ``: + +``` +cargo run --bin move-unit-test -i 0 MyModule.move +Running Move unit tests +[ TIMEOUT ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ TIMEOUT ] 0x1::MyModule::make_sure_zero_coin_fails +[ TIMEOUT ] 0x1::MyModule::test_has_coin + +Test failures: + +Failures in 0x1::MyModule: + +┌── make_sure_non_zero_coin_passes ────── +│ Test timed out +└────────────────── + + +┌── make_sure_zero_coin_fails ────── +│ Test timed out +└────────────────── + + +┌── test_has_coin ────── +│ Test timed out +└────────────────── + +Test result: FAILED. Total tests: 3; passed: 0; failed: 3 +``` + +#### `-s` or `--statistics` +With these flags you can gather statistics about the tests run and report the runtime and gas used for each test. For example, if we wanted to see the statistics for the tests in the `MyModule` example above: + +``` +$ cargo run --bin move-unit-test MyModule.move -s +Running tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +[ PASS ] 0x1::MyModule::test_has_coin + +Test Statistics: + +┌───────────────────────────────────────────────┬────────────┬───────────────────────────┐ +│ Test Name │ Time │ Gas Used │ +├───────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::MyModule::make_sure_non_zero_coin_passes │ 0.005 │ 1 │ +├───────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::MyModule::make_sure_zero_coin_fails │ 0.003 │ 1 │ +├───────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::MyModule::test_has_coin │ 0.004 │ 1 │ +└───────────────────────────────────────────────┴────────────┴───────────────────────────┘ + +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +#### `-g` or `--state-on-error` +These flags will print the global state for any test failures. e.g., if we added the following (failing) test to the `MyModule` example: + +``` +module 0x1::MyModule { + ... + #[test(a = @0x1)] + fun test_has_coin_bad(a: signer) { + publish_coin(&a); + assert(has_coin(@0x1), 0); + assert(has_coin(@0x2), 1); + } +} +``` + +we would get get the following output: + +``` +$ cargo run --bin move-unit-test MyModule.move -g +Running tests +[ PASS ] 0x1::MyModule::make_sure_non_zero_coin_passes +[ PASS ] 0x1::MyModule::make_sure_zero_coin_fails +[ PASS ] 0x1::MyModule::test_has_coin +[ FAIL ] 0x1::MyModule::test_has_coin_bad + +Test failures: + +Failures in 0x1::MyModule: + +┌── test_has_coin_bad ────── +│ error: +│ +│ ┌── MyModule.move:46:9 ─── +│ │ +│ 46 │ assert(has_coin(@0x2), 1); +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to abort but it aborted with 1 here +│ · +│ 43 │ fun test_has_coin_bad(a: signer) { +│ │ ----------------- In this function in 0x1::MyModule +│ │ +│ +│ +│ ────── Storage state at point of failure ────── +│ 0x1: +│ => key 0x1::MyModule::MyCoin { +│ value: 1 +│ } +│ +└────────────────── + +Test result: FAILED. Total tests: 4; passed: 3; failed: 1 +``` + +## Ongoing Work + +Support for test-only native functions is currently being added to the unit testing framework. With this addition comes a new way of creating an arbitrary number of `signer` values in test-only code. We expect these features to be available in release 1.4. + +We also plan to support running Move unit tests from the Move CLI and expect that this to be supported in release 1.4. + +## Alternatives + +In the development of unit tests, there were a couple of alternatives considered, some of which you as a Move programmer have at your disposal already, so we highlight the differences here. + +### Expected Value Tests + +Move already supports [expected value tests](https://github.com/move-language/move/tree/main/language/tools/move-cli#testing-with-the-move-cli) in the Move CLI, however these cover a different aspect of testing for Move. In particular, there is no concept of test-only code and test-only dependencies, which makes testing non-public functions much more difficult. Additionally, each expected value test entry must be a transaction or script function. Because of this, the expected value tests rely on a specific Move adapter implementation, whereas the unit tests do not rely on an adapter implementation and rely solely on the Move compiler and VM. + +Due to the design of unit tests, unit tests make it easier to test the individual units of code that comprise a Move module. However, because the unit tests do not require or use an adapter, they do not support certain features that you may wish to test. E.g., there is no way in Move unit tests to query if a specific event has been emitted. + +### Test Modules + +The unit tests for Move are function and annotation based: each test and test-only members are declared by attaching an annotation to them. During development we also considered a module-based approach where a separate test module could be declared that contained the tests for a module (and that the compiler would inline so the tests could access private functions and construct datatypes declared in the module). We decided against supporting such an option at this time for simplicity, and to make the additional syntax and the semantics as close as possible to what currently exists in Move, but that option could still be added in the future. diff --git a/vendors/move/crates/changes/5-named-addresses.md b/vendors/move/crates/changes/5-named-addresses.md new file mode 100644 index 000000000..936db6803 --- /dev/null +++ b/vendors/move/crates/changes/5-named-addresses.md @@ -0,0 +1,200 @@ +# Named Addresses + +- Status: Implemented in Move 1.4, updated in Move 1.5 + +## Introduction + +Named addresses are a new source language only feature. (That is, the named address feature is +compiled away and not present in the Move bytecode format). The feature allows names to be used in +place of numerical values in any spot where addresses are used. Named addresses are declared as top +level elements (outside of modules and scripts) in Move Packages, or passed as +arguments to the Move compiler. + +With the landing of this feature, Move standard library modules now reside under the address `Std`, +e.g. `std::vector`. Similarly, Diem Framework modules now reside under the address `DiemFramework`, +e.g. `DiemFramework::XUS`. + +Named address declarations are opaque, meaning they must be accessed via the name and not their +underlying numeric value. Any existing code must be updated to use named addresses when accessing +standard library or Diem Framework modules. + +Alongside this change, there is new syntax for address literals when used as expression values, e.g. +`let addr = @0x42;`. + +## Motivations + +Fixed, numerical addresses were "good enough" for the language starting off, but the inability to +set addresses via a configuration at build time severely hinders code portability and usability. +Additionally, the lack of named address support has been painful both for account configuration in +testing and for basic readability of code. + +To combat this, we are adding named addresses. They compile down to the same address system that +exists today, but it greatly increases the portability, testability, and readability of source +language programs. + +## Description + +### New Address Literal Syntax + +Addresses now come in two flavors, named or numerical. The syntax for a named address follows the +same rules for any named identifier in Move. The syntax of a numerical address is no longer +restricted to `0x`-prefixed values, and now any valid numerical literal can be used. + +To make room for the named address feature, address expression values have a new syntax. This new +syntax reduces the complexity around named addresses as it prevents shadowing issues around module +members (specifically constants) and local variables. + +In the old syntax, all address values began with `0x` and this hex prefix could not be used for +integer values. In the new syntax, all address values are prefixed with `@`. Following the `@` +operator any valid address can be used. For example: + +```move +let _: u8 = 0x1u8; +let _: u64 = 0x42u64; +let _: u128 = 0x42u128; +let a1: address = @std; +let a2: address = @66; +let a3: address = @0x42; +``` + +You can think of `@` as an operator that takes an address from being a namespace item to an +expression item. + +Named addresses are not declared in Move source code. Instead they +must be declared---and given a value---when invoking the Move compiler. E.g., + +```bash +cargo run --bin move-build --addresses MyAddr=0x42 ... +``` + +A named address can be used in both module accesses and as expression values (with the new +`@` syntax) + +```move +script { + fun example() { + MyAddr::M::foo(@MyAddr); + } +} +``` + +A named address can be used multiple times throughout a program. + +```move +// file1.move +module MyAddr::M { + ... +} +``` + +```move +// file2.move +address MyAddr { +module N { + ... +} +} +``` + +### Assigning Named Addresses + +Named addresses can only be assigned a value by passing their value as a parameter to the compiler with `=`: + +```bash +cargo run --bin move-build --addresses MyAddr=0xC0FFEE ... +``` + +An address can be assigned any number of times on the command line as long as it is given only _one_ value. +The following would be fine, since the address `MyAddr` is given the same value in both assignments: + +```bash +cargo run --bin move-build --addresses MyAddr=0xC0FFEE MyAddr=12648430 ... # decimal representation of 0xC0FFEE +``` + +Assigning `MyAddr` two different values will result in an error: + +```bash +cargo run --bin move-build --addresses MyAddr=0xC0FFEE MyAddr=0xDEADBEEF... # ERROR! +``` + +### Opaqueness + +Address assignments, and the name system as whole, only exist at the source +language level and during compilation. Names will be fully substituted for +their value at the byte code level. So the example from before would be +equivalent to + +```move +script { + fun example() { + 0xC0FFEE::M::foo(@0xC0FFEE); + } +} +``` + +But at the source language level, the two are not interchangeable. If we had the declaration: + +```move +module MyAddr::M { + public fun bar() {} +} +``` + +The function `M::bar` _must_ be accessed through the `MyAddr` named address, not through the +numerical value assigned to it. + +For example: + +```move +script { + fun example() { + // ERROR! 0xC0FFEE::M::bar(); + MyAddr::M::bar() + } +} +``` + +## Move Standard Library and Diem Framework Modules + +As mentioned above, all standard library modules now live in `Std` and all Diem Framework modules +live in `DiemFramework`. The `DiemFramework` address is set to `0x1` and this hard-coded assignment +will be fine. However, our hope is to allow `Std` to be assigned different numerical values +depending on the deployment of those modules. For now, `Std` has a hardcoded assignment of `0x1`. +See the 'Future Work' section below for details about how this might work in the future. + +## Backwards Compatibility + +Since, all standard library modules and all Diem Framework modules live in `Std` and `DiemFramework` +respectively, source code must be updated to use those named addresses. The named addresses are +opaque, so the numeric values can no longer be used to access the modules. For example, any use of +`0x1::Vector` must now be `std::vector`. + +Note, as this is just a syntactic change, the compiled module binaries will not be affected. + +## Update for release 1.5 + +The support for assigning values to named addresses in Move source code and declaring named addresses in release 1.4 + +```move +address MyAddr = 0x19; +``` + +and + +```move +address MyAddr; +``` + +was removed. + +Support for assigning address values was added to the command line and compiler +options were added for use in Move packages and the Move command line as described above. + + +## Future Work + +Named address support will be expanded in a new package system. The intent is that with this system, +a Move program will never assign a value to a named address within the `*.move` files. Instead, all +assignment of a named addresses will exist in a config file, similar to Rust's `Cargo.toml` files. +To enable this package system, additional support will likely be needed from the compiler for +configuring and assigning named addreses. diff --git a/vendors/move/crates/changes/6-phantom-type-params.md b/vendors/move/crates/changes/6-phantom-type-params.md new file mode 100644 index 000000000..81c454e2a --- /dev/null +++ b/vendors/move/crates/changes/6-phantom-type-params.md @@ -0,0 +1,112 @@ +# Phantom Type Parameters + +- Status: Implemented in Move 1.4 + +## Introduction + +A _phantom type parameter_ is one that doesn't show up at runtime, but is checked statically at +compile time. Phantom type parameters can be useful in a couple of situations. For example, the +struct `Event::EventHandle` in the Move Standard library doesn't contain any field of type `T`, +but uses the type parameter to ensure at the type level that the handle can only be used for +messages of type `T`. Another prominent example is `Diem::Diem`, which is generic on a +`CoinType` specifying the currency of the coin and allowing code to be written generically on any +currency. As a last example, the capabilities in `Vault` also rely heavily on phantom type +parameters. + +Previously, Move's type system didn't make a difference on whether a type parameter was phantom, but +with this new feature, a struct's type parameter can be explicitly declared as phantom. A parameter +declared as phantom is not considered when computing the +[conditional abilities with generic types](3-abilities.md#Conditional-Abilities-with-Generic-Types). +For this relaxed rule to be sound, Move's type system guarantees that a parameter declared as +phantom is either not used at all in the struct definition, or it is only used as an argument to +type parameters also declared as phantom. + +## Motivations + +Previously, defining a struct `S` with a phantom type parameter required spurious ability +annotations to satisfy the requirements of the abilities declared for `S`. This resulted in +increased chance of bugs and security vulnerability because types had to be weakened with +unnecessary ability declarations. Moreover, the spurious annotations were infectious, requiring many +functions generic on the phantom type parameter to also include the necessary constraints. With the +new feature, arguments to phantom type parameters are not considered when deriving the abilities for +generic types, thus avoiding the need for spurious ability annotations. + +For example, `Diem::Diem` is declared with the ability `key`. This required all arguments +to `CoinType` to be declared with `store`. Specifically, the types `XUS::XUS` and `XDX::XDX` were +forced to have a `store` annotation even though they were never stored in global storage! Moreover +the extra `store` requirement polluted the entire Diem Framework and many functions had to specify +extra `store` constraints on their type parameters. With the new feature, `Diem::Diem` now +declares `CoinType` to be phantom which avoids the spurious `store` annotations sprinkled over the +code. + +## Description + +### Declaration + +In a struct definition a type parameter can be declared as phantom by adding the `phantom` keyword +before its declaration. If a type parameter is declared as phantom we say it is a phantom type +parameter. When defining a struct, Move's type checker ensures that every phantom type parameter is +either not used inside the struct definition or it is only used as an argument to a phantom type +parameter. + +More formally, if a type is used as an argument to a phantom type parameter we say the type appears +in _phantom position_. With this definition in place, the rule for the correct use of phantom +parameters can be specified as follows: **A phantom type parameter can only appear in phantom +position**. + +The following two examples show valid uses of phantom parameters. In the first one, the parameter +`T1` is not used at all inside the struct definition. In the second one, the parameter `T1` is only +used as an argument to a phantom type parameter. + +``` +struct S1 { f: u64 } + ^^ + Ok: T1 does not appear inside the struct definition + + +struct S2 { f: S1 } + ^^ + Ok: T1 appears in phantom position +``` + +The following code shows examples of violations of the rule: + +``` + +struct S1 { f: T } + ^ + Error: Not a phantom position + +struct S2 { f: T } + +struct S3 { f: S2 } + ^ + Error: Not a phantom position +``` + +### Instantiation + +When instantiating a struct, the arguments to phantom parameters are excluded when deriving the +struct abilities. For example, consider the following code: + +``` +struct S has copy { f: T1 } +struct NoCopy {} +struct HasCopy has copy {} +``` + +Consider now the type `S`. Since `S` is defined with `copy` and all non-phantom +arguments have copy then `S` also has copy. + +### Phantom Type Parameters with Ability Constraints + +Ability constraints and phantom type parameters are orthogonal features in the sense that phantom +parameters can be declared with ability constraints. When instantiating a phantom type parameter +with an ability constraint, the type argument has to satisfy that constraint, even though the +parameter is phantom. For example, the following definition is perfectly valid: + +``` +struct S {} +``` + +The usual restrictions apply and `T` can only be instantiated with arguments having `copy`. diff --git a/vendors/move/crates/changes/7-packages.md b/vendors/move/crates/changes/7-packages.md new file mode 100644 index 000000000..dae0e7179 --- /dev/null +++ b/vendors/move/crates/changes/7-packages.md @@ -0,0 +1,327 @@ +# Packages + +* Status: Implemented in Move 1.5 + +## Introduction + +Packages are a new source feature to allow Move programmers to more easily +re-use code and share it across projects. The Move package system allows +programmers to easily: +* Define a package containing Move code; +* Parameterize a package by named addresses; +* Use a package in Move code and instantiate its named addresses; +* Build packages; and +* Work with a common interface around compiled Move artifacts. + +## Motivation + +Until now, when writing Move you had no easy options of being able to +package Move code into reusable chunks that could be used by others. There +was no common compiled object model or on-disk representation of compiled +Move code and its associated artifacts, e.g., source maps and generated +documentation. And finally, there was no way of easily managing named +addresses that spanned "logical groupings" of Move code. + +The Move package system aims to make these actions easier by providing a +common compiled-object model and access to both compiled bytecode and + associated compilation artifacts along with ways to: +* Declare logical packages of Move code; +* Import and use packages; +* Compile and generate associated compilation artifacts from packages; and +* Manage--expose and instantiate--named addresses in packages. + +## Package Layout and Manifest Syntax + +A Move package source directory contains a `Move.toml` package manifest +file along with a set of subdirectories: + +``` +a_move_package +├── Move.toml (required) +├── sources (required) +├── examples (optional, test & dev mode) +├── scripts (optional) +├── doc_templates (optional) +└── tests (optional, test mode) +``` + +The directories marked `required` _must_ be present in order for the directory +to be considered a Move package and to be compiled. Optional directories can +be present, and if so will be included in the compilation process. Depending on +the mode that the package is built with (`test` or `dev`), the `tests` and +`examples` directories will be included as well. + +The `sources` directory can contain both Move modules and Move scripts (both +transaction scripts and modules containing script functions). The `examples` +directory can hold additional code to be used only for development and/or +tutorial purposes that will not be included when compiled outside `test` or +`dev` mode. + +A `scripts` directory is supported so transaction scripts can be separated +from modules if that is desired by the package author. The `scripts` +directory will always be included for compilation if it is present. +Documentation will be built using any [documentation +templates](../move-prover/doc/user/docgen.md) present in the +`doc_templates` directory. + +### Move.toml + +The Move package manifest is defined within the `Move.toml` file and has the +following syntax. Optional fields are marked with `*`, `+` denotes +one or more elements: + +``` +[package] +name = # e.g., "MoveStdlib" +version = ".." # e.g., "0.1.1" +license* = # e.g., "MIT", "GPL", "Apache 2.0" +authors* = [] # e.g., ["Joe Smith (joesmith@noemail.com)", "Jane Smith (janesmith@noemail.com)"] + +[addresses] # (Optional section) Declares named addresses in this package and instantiates named addresses in the package graph +# One or more lines declaring named addresses in the following format + = "_" | "" # e.g., Std = "_" or Addr = "0xC0FFEECAFE" + +[dependencies] # (Optional section) Paths to dependencies and instantiations or renamings of named addresses from each dependency +# One or more lines declaring dependencies in the following format + = { local = , addr_subst* = { ( = ( | ""))+ } } + +[dev-addresses] # (Optional section) Same as [addresses] section, but only included in "dev" and "test" modes +# One or more lines declaring dev named addresses in the following format + = "_" | "" # e.g., Std = "_" or Addr = "0xC0FFEECAFE" + +[dev-dependencies] # (Optional section) Same as [dependencies] section, but only included in "dev" and "test" modes +# One or more lines declaring dev dependencies in the following format + = { local = , addr_subst* = { ( = ( |
))+ } } +``` + +An example of the most minimal package manifest: + +``` +[package] +name = "AName" +version = "0.0.0" +``` + +An example of a more standard package manifest that also includes the Move +standard library and instantiates the named address `Std` from it with the +address value `0x1`: + +``` +[package] +name = "AName" +version = "0.0.0" +license = "Apache 2.0" + +[addresses] +AddressToBeFilledIn = "_" +SpecifiedAddress = "0xB0B" + +[dependencies] +MoveStdlib = { local = "/move-stdlib", addr_subst = { "Std" = "0x1" } } + +[dev-addresses] # For use when developing this module +AddressToBeFilledIn = "0x101010101" +``` + +Most of the sections in the package manifest are self explanatory, but named +addresses can be a bit difficult to understand so it's worth examining them in +a bit more detail. + +## Named Addresses During Compilation + +Recall that Move has [named addresses](./5-named-addresses.md) and that +named addresses cannot be declared in Move. Because of this, until now +named addresses and their values needed to be passed to the compiler on the +command line. With the Move package system this is no longer needed, and +you can declare named addresses in the package, instantiate other named +addresses in scope, and rename named addresses from other packages within +the Move package system manifest file. Let's go through each of these +individually: + +## Declaration + +Let's say we have a Move module in `example_pkg/sources/A.move` as follows: +```move +module NamedAddr::A { + public fun x(): address { @NamedAddr } +} +``` + +We could in `example_pkg/Move.toml` declare the named address `NamedAddr` in +two different ways. The first: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +NamedAddr = "_" +``` + +Declares `NamedAddr` as a named address in the package `ExamplePkg` and +that _this address can be any valid address value_. Therefore an importing +package can pick the value of the named address `NamedAddr` to be any address +it wishes. Intuitively you can think of this as parameterizing the package +`ExamplePkg` by the named address `NamedAddr`, and the package can then be +instantiated later on by an importing package. + +`NamedAddr` can also be declared as: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +NamedAddr = "0xCAFE" +``` + +which states that the named address `NamedAddr` is exactly `0xCAFE` and cannot be +changed. This is useful so other importing packages can use this named +address without needing to worry about the exact value assigned to it. + +With these two different declaration methods, there are two ways that +information about named addresses can flow in the package graph: +* The former ("unassigned named addresses") allows named address values to flow + from the importation site to the declaration site. +* The latter ("assigned named addresses") allows named address values to flow + from the declaration site upwards in the package graph to usage sites. + +With these two methods for flowing named address information throughout the +package graph the rules around scoping and renaming become important to +understand. + +## Scoping and Renaming of Named Addresses + +A named address `N` in a package `P` is in scope if: +1. It declares a named address `N`; or +2. A package in one of `P`'s transitive dependencies declares the named address + `N` and there is a dependency path in the package graph between between `P` and the + declaring package of `N` with no renaming of `N`. + +Additionally, every named address in a package is exported. Because of this and +the above scoping rules each package can be viewed as coming with a set of +named addresses that will be brought into scope when the package is imported, +e.g., if the `ExamplePkg` package was imported, that importation would bring +into scope the `NamedAddr` named address. Because of this, if `P` imports two +packages `P1` and `P2` both of which declare a named address `N` an issue +arises in `P`: which "`N`" is meant when `N` is referred to in `P`? The one +from `P1` or `P2`? To prevent this ambiguity around which package a named +address is coming from, we enforce that the sets of scopes introduced by all +dependencies in a package are disjoint, and provide a way to _rename named +addresses_ when the package that brings them into scope is imported. + +Renaming a named address when importing can be done as follows in our `P`, +`P1`, and `P2` example above: + +``` +[package] +name = "P" +... +[dependencies] +P1 = { local = "some_path_to_P1", addr_subst = { "P1N" = "N" } } +P2 = { local = "some_path_to_P2" } +``` + +With this renaming `N` refers to the `N` from `P2` and `P1N` will refer to `N` +coming from `P1`: + +``` +module N::A { + public fun x(): address { @P1N } +} +``` + +It is important to note that _renaming is not local_: once a named address `N` +has been renamed to `N2` in a package `P` all packages that import `P` will not +see `N` but only `N2` unless `N` is reintroduced from outside of `P`. This is +why rule (2) in the scoping rules at the start of this section specifies a +"dependency path in the package graph between between `P` and the declaring +package of `N` with no renaming of `N`." + +### Instantiation + +Named addresses can be instantiated multiple times across the package graph as +long as it is always with the same value. It is an error if the same named +address (regardless of renaming) is instantiated with differing values across +the package graph. + +A Move package can only be compiled if all named addresses resolve to a value. +This presents issues if the package wishes to expose an uninstantiated named +address. This is what the `[dev-addresses]` section solves. This section can +set values for named addresses, but cannot introduce any named addresses. +Additionally, only the `[dev-addresses]` in the root package are included in +`dev` mode. For example a root package with the following manifest would not compile +outside of `dev` mode since `NamedAddr` would be uninstantiated: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +NamedAddr = "_" + +[dev-addresses] +NamedAddr = "0xC0FFEE" +``` + +## Usage, Artifacts, and Data Structures + +The Move package system comes with a command line option as part of the Move +CLI `move `. Unless a +particular path is provided, all package commands will run in the current working +directory. The full list of commands and flags for the Move CLI can be found by +running `move --help`. + +### Usage + +A package can be compiled either through the Move CLI commands, or as a library +command in Rust with the function `compile_package`. This will create a +`CompiledPackage` that holds the compiled bytecode along with other compilation +artifacts (source maps, documentation, ABIs) in memory. This `CompiledPackage` +can be converted to an `OnDiskPackage` and vice versa -- the latter being the data of +the `CompiledPackage` laid out in the file system in the following format: + +``` +a_move_package +├── Move.toml +... +└── build + ├── + │   ├── BuildInfo.yaml + │   ├── bytecode_modules + │   │   └── *.mv + │   ├── source_maps + │   │   └── *.mvsm + │ ├── bytecode_scripts + │ │   └── *.mv + │ ├── abis + │ │   ├── *.abi + │ │   └── /*.abi + │   └── sources + │   └── *.move + ... + └── + ├── BuildInfo.yaml + ... + └── sources +``` + +See the `move-package` crate for more information on these data structures and +how to use the Move package system as a Rust library. + +## Future Work + +We intend on adding support for the following features over time: +* Adding a flag to print the named addresses in scope and their values for each + of the dependencies of the package being built. +* Support renaming multiple names from dependencies to one named address, e.g. + the following will not work today, but we'd like to support it: + ``` + ... + [dependencies] + A = { local = "...", addr_subst = { "Addr" = "A" } } + B = { local = "...", addr_subst = { "Addr" = "B" } } + ``` +* Default importation of the Move standard library: currently the Move standard + library must be imported in the package in order to use unit testing + features. diff --git a/vendors/move/crates/documentation/book/.gitignore b/vendors/move/crates/documentation/book/.gitignore new file mode 100644 index 000000000..5a0bf0317 --- /dev/null +++ b/vendors/move/crates/documentation/book/.gitignore @@ -0,0 +1 @@ +/book diff --git a/vendors/move/crates/documentation/book/README.md b/vendors/move/crates/documentation/book/README.md new file mode 100644 index 000000000..6398c472d --- /dev/null +++ b/vendors/move/crates/documentation/book/README.md @@ -0,0 +1,38 @@ +--- +id: move-book +title: Move Book +custom_edit_url: https://github.com/move-language/move/edit/main/language/documentation/book/README.md +--- + +In order to update the Move book and preview changes to it you'll need to +install +[`mdbook`](https://rust-lang.github.io/mdBook/guide/installation.html). You +can do this via `cargo install mdbook`. + +After installing mdbook, you can preview changes via either `mdbook serve`, +or if you want the output to change as you make changes to the book you can +use `mdbook watch`. More information on options can be found at the [mdbook +website](https://rust-lang.github.io/mdBook/). + +Once you are happy with your changes to the Move book, you can create a PR to +update the Move book website. This is the process that has been used in +the past and is known to work, but there may be a better way: + +1. Run `mdbook build` in this directory. This will create a directory +called `book`. Copy this to some location `L` outside of the Move git tree. + +2. Make sure your upstream is up-to-date and checkout to `upstream/gh-pages`. + +3. Once you have checked out to `upstream/gh-pages`, make sure you are at the +root of the repo. You should see a number of `.html` files. You can now +move all contents in `L` to this location: `mv L/* .` + +4. Once this is done inspect things to make sure the book looks the way you +want. If everything looks good submit a PR to the **`gh-pages`** branch of the +main Move repo. + +After this the normal PR process is followed. Once the PR has been accepted and +lands the updated Move book should be visible immediately. + +**NB:** When adding a new (sub)section to the book you _must_ include the new +file in the `SUMMARY.md` file otherwise it will not appear in the updated book. diff --git a/vendors/move/crates/documentation/book/book.toml b/vendors/move/crates/documentation/book/book.toml new file mode 100644 index 000000000..8ead41f87 --- /dev/null +++ b/vendors/move/crates/documentation/book/book.toml @@ -0,0 +1,12 @@ +[book] +title = "The Move Book" +description = "Move book maintained by the Move core team." +authors = ["The Move Contributors"] +language = "en" +multilingual = false +src = "src" + +[output.html] +git-repository-url = "https://github.com/move-language/move" +git-repository-icon = "fa-github" +edit-url-template = "https://github.com/move-language/move/edit/main/language/documentation/book/{path}" diff --git a/vendors/move/crates/documentation/book/src/SUMMARY.md b/vendors/move/crates/documentation/book/src/SUMMARY.md new file mode 100644 index 000000000..1ed9cbc12 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/SUMMARY.md @@ -0,0 +1,45 @@ +# The Move Programming Language + +[Introduction](introduction.md) + +## Getting Started + +- [Modules and Scripts](modules-and-scripts.md) +- [Move Tutorial](creating-coins.md) + +## Primitive Types + +- [Integers](integers.md) +- [Bool](bool.md) +- [Address](address.md) +- [Vector](vector.md) +- [Signer](signer.md) +- [References](references.md) +- [Tuples and Unit](tuples.md) + +## Basic Concepts + +- [Local Variables and Scopes](variables.md) +- [Equality](equality.md) +- [Abort and Assert](abort-and-assert.md) +- [Conditionals](conditionals.md) +- [While and Loop](loops.md) +- [Functions](functions.md) +- [Structs and Resources](structs-and-resources.md) +- [Constants](constants.md) +- [Generics](generics.md) +- [Type Abilities](abilities.md) +- [Uses and Aliases](uses.md) +- [Friends](friends.md) +- [Packages](packages.md) +- [Unit Tests](unit-testing.md) + +## Global Storage + +- [Global Storage Structure](global-storage-structure.md) +- [Global Storage Operators](global-storage-operators.md) + +## Reference + +- [Standard Library](standard-library.md) +- [Coding Conventions](coding-conventions.md) diff --git a/vendors/move/crates/documentation/book/src/abilities.md b/vendors/move/crates/documentation/book/src/abilities.md new file mode 100644 index 000000000..2abe21b8e --- /dev/null +++ b/vendors/move/crates/documentation/book/src/abilities.md @@ -0,0 +1,244 @@ +# Abilities + +Abilities are a typing feature in Move that control what actions are permissible for values of a given type. This system grants fine grained control over the "linear" typing behavior of values, as well as if and how values are used in global storage. This is implemented by gating access to certain bytecode instructions so that for a value to be used with the bytecode instruction, it must have the ability required (if one is required at all—not every instruction is gated by an ability). + + + +## The Four Abilities + +The four abilities are: + +* [`copy`](#copy) + * Allows values of types with this ability to be copied. +* [`drop`](#drop) + * Allows values of types with this ability to be popped/dropped. +* [`store`](#store) + * Allows values of types with this ability to exist inside a struct in global storage. +* [`key`](#key) + * Allows the type to serve as a key for global storage operations. + +### `copy` + +The `copy` ability allows values of types with that ability to be copied. It gates the ability to copy values out of local variables with the [`copy`](./variables.md#move-and-copy) operator and to copy values via references with [dereference `*e`](./references.md#reading-and-writing-through-references). + +If a value has `copy`, all values contained inside of that value have `copy`. + +### `drop` + +The `drop` ability allows values of types with that ability to be dropped. By dropped, we mean that value is not transferred and is effectively destroyed as the Move program executes. As such, this ability gates the ability to ignore values in a multitude of locations, including: +* not using the value in a local variable or parameter +* not using the value in a [sequence via `;`](./variables.md#expression-blocks) +* overwriting values in variables in [assignments](./variables.md#assignments) +* overwriting values via references when [writing `*e1 = e2`](./references.md#reading-and-writing-through-references). + +If a value has `drop`, all values contained inside of that value have `drop`. + +### `store` + +The `store` ability allows values of types with this ability to exist inside of a struct (resource) in global storage, *but* not necessarily as a top-level resource in global storage. This is the only ability that does not directly gate an operation. Instead it gates the existence in global storage when used in tandem with `key`. + +If a value has `store`, all values contained inside of that value have `store` + +### `key` + +The `key` ability allows the type to serve as a key for [global storage operations](./global-storage-operators.md). It gates all global storage operations, so in order for a type to be used with `move_to`, `borrow_global`, `move_from`, etc., the type must have the `key` ability. Note that the operations still must be used in the module where the `key` type is defined (in a sense, the operations are private to the defining module). + +If a value has `key`, all values contained inside of that value have `store`. This is the only ability with this sort of asymmetry. + +## Builtin Types + +Most primitive, builtin types have `copy`, `drop`, and `store` with the exception of `signer`, which just has `drop` + +* `bool`, `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, and `address` all have `copy`, `drop`, and `store`. +* `signer` has `drop` + * Cannot be copied and cannot be put into global storage +* `vector` may have `copy`, `drop`, and `store` depending on the abilities of `T`. + * See [Conditional Abilities and Generic Types](#conditional-abilities-and-generic-types) for more details. +* Immutable references `&` and mutable references `&mut` both have `copy` and `drop`. + * This refers to copying and dropping the reference itself, not what they refer to. + * References cannot appear in global storage, hence they do not have `store`. + +None of the primitive types have `key`, meaning none of them can be used directly with the [global storage operations](./global-storage-operators.md). + +## Annotating Structs + +To declare that a `struct` has an ability, it is declared with `has ` after the struct name but before the fields. For example: + +```move +struct Ignorable has drop { f: u64 } +struct Pair has copy, drop, store { x: u64, y: u64 } +``` + +In this case: `Ignorable` has the `drop` ability. `Pair` has `copy`, `drop`, and `store`. + + +All of these abilities have strong guarantees over these gated operations. The operation can be performed on the value only if it has that ability; even if the value is deeply nested inside of some other collection! + +As such: when declaring a struct’s abilities, certain requirements are placed on the fields. All fields must satisfy these constraints. These rules are necessary so that structs satisfy the reachability rules for the abilities given above. If a struct is declared with the ability... + +* `copy`, all fields must have `copy`. +* `drop`, all fields must have `drop`. +* `store`, all fields must have `store`. +* `key`, all fields must have `store`. + * `key` is the only ability currently that doesn’t require itself. + +For example: + +```move +// A struct without any abilities +struct NoAbilities {} + +struct WantsCopy has copy { + f: NoAbilities, // ERROR 'NoAbilities' does not have 'copy' +} +``` + +and similarly: + +```move +// A struct without any abilities +struct NoAbilities {} + +struct MyResource has key { + f: NoAbilities, // Error 'NoAbilities' does not have 'store' +} +``` + +## Conditional Abilities and Generic Types + +When abilities are annotated on a generic type, not all instances of that type are guaranteed to have that ability. Consider this struct declaration: + +``` +struct Cup has copy, drop, store, key { item: T } +``` + +It might be very helpful if `Cup` could hold any type, regardless of its abilities. The type system can *see* the type parameter, so it should be able to remove abilities from `Cup` if it *sees* a type parameter that would violate the guarantees for that ability. + +This behavior might sound a bit confusing at first, but it might be more understandable if we think about collection types. We could consider the builtin type `vector` to have the following type declaration: + +``` +vector has copy, drop, store; +``` + +We want `vector`s to work with any type. We don't want separate `vector` types for different abilities. So what are the rules we would want? Precisely the same that we would want with the field rules above. So, it would be safe to copy a `vector` value only if the inner elements can be copied. It would be safe to ignore a `vector` value only if the inner elements can be ignored/dropped. And, it would be safe to put a `vector` in global storage only if the inner elements can be in global storage. + +To have this extra expressiveness, a type might not have all the abilities it was declared with depending on the instantiation of that type; instead, the abilities a type will have depends on both its declaration **and** its type arguments. For any type, type parameters are pessimistically assumed to be used inside of the struct, so the abilities are only granted if the type parameters meet the requirements described above for fields. Taking `Cup` from above as an example: + +* `Cup` has the ability `copy` only if `T` has `copy`. +* It has `drop` only if `T` has `drop`. +* It has `store` only if `T` has `store`. +* It has `key` only if `T` has `store`. + +Here are examples for this conditional system for each ability: + +### Example: conditional `copy` + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun example(c_x: Cup, c_s: Cup) { + // Valid, 'Cup' has 'copy' because 'u64' has 'copy' + let c_x2 = copy c_x; + // Valid, 'Cup' has 'copy' because 'S' has 'copy' + let c_s2 = copy c_s; +} + +fun invalid(c_account: Cup, c_n: Cup) { + // Invalid, 'Cup' does not have 'copy'. + // Even though 'Cup' was declared with copy, the instance does not have 'copy' + // because 'signer' does not have 'copy' + let c_account2 = copy c_account; + // Invalid, 'Cup' does not have 'copy' + // because 'NoAbilities' does not have 'copy' + let c_n2 = copy c_n; +} +``` + +### Example: conditional `drop` + +``` +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun unused() { + Cup { item: true }; // Valid, 'Cup' has 'drop' + Cup { item: S { f: false }}; // Valid, 'Cup' has 'drop' +} + +fun left_in_local(c_account: Cup): u64 { + let c_b = Cup { item: true }; + let c_s = Cup { item: S { f: false }}; + // Valid return: 'c_account', 'c_b', and 'c_s' have values + // but 'Cup', 'Cup', and 'Cup' have 'drop' + 0 +} + +fun invalid_unused() { + // Invalid, Cannot ignore 'Cup' because it does not have 'drop'. + // Even though 'Cup' was declared with 'drop', the instance does not have 'drop' + // because 'NoAbilities' does not have 'drop' + Cup { item: NoAbilities {}}; +} + +fun invalid_left_in_local(): u64 { + let n = Cup { item: NoAbilities {}}; + // Invalid return: 'c_n' has a value + // and 'Cup' does not have 'drop' + 0 +} +``` + +### Example: conditional `store` + +``` +struct Cup has copy, drop, store { item: T } + +// 'MyInnerResource' is declared with 'store' so all fields need 'store' +struct MyInnerResource has store { + yes: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} + +// 'MyResource' is declared with 'key' so all fields need 'store' +struct MyResource has key { + yes: Cup, // Valid, 'Cup' has 'store' + inner: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} +``` + +### Example: conditional `key` + +``` +struct NoAbilities {} +struct MyResource has key { f: T } + +fun valid(account: &signer) acquires MyResource { + let addr = signer::address_of(account); + // Valid, 'MyResource' has 'key' + let has_resource = exists>(addr); + if (!has_resource) { + // Valid, 'MyResource' has 'key' + move_to(account, MyResource { f: 0 }) + }; + // Valid, 'MyResource' has 'key' + let r = borrow_global_mut>(addr) + r.f = r.f + 1; +} + +fun invalid(account: &signer) { + // Invalid, 'MyResource' does not have 'key' + let has_it = exists>(addr); + // Invalid, 'MyResource' does not have 'key' + let NoAbilities {} = move_from(addr); + // Invalid, 'MyResource' does not have 'key' + move_to(account, NoAbilities {}); + // Invalid, 'MyResource' does not have 'key' + borrow_global(addr); +} +``` diff --git a/vendors/move/crates/documentation/book/src/abort-and-assert.md b/vendors/move/crates/documentation/book/src/abort-and-assert.md new file mode 100644 index 000000000..ce3e87478 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/abort-and-assert.md @@ -0,0 +1,207 @@ +# Abort and Assert + +[`return`](./functions.md) and `abort` are two control flow constructs that end execution, one for +the current function and one for the entire transaction. + +More information on [`return` can be found in the linked section](./functions.md) + +## `abort` + +`abort` is an expression that takes one argument: an **abort code** of type `u64`. For example: + +```move +abort 42 +``` + +The `abort` expression halts execution the current function and reverts all changes made to global +state by the current transaction. There is no mechanism for "catching" or otherwise handling an +`abort`. + +Luckily, in Move transactions are all or nothing, meaning any changes to global storage are made all +at once only if the transaction succeeds. Because of this transactional commitment of changes, after +an abort there is no need to worry about backing out changes. While this approach is lacking in +flexibility, it is incredibly simple and predictable. + +Similar to [`return`](./functions.md), `abort` is useful for exiting control flow when some +condition cannot be met. + +In this example, the function will pop two items off of the vector, but will abort early if the +vector does not have two items + +```move= +use std::vector; +fun pop_twice(v: &mut vector): (T, T) { + if (vector::length(v) < 2) abort 42; + + (vector::pop_back(v), vector::pop_back(v)) +} +``` + +This is even more useful deep inside a control-flow construct. For example, this function checks +that all numbers in the vector are less than the specified `bound`. And aborts otherwise + +```move= +use std::vector; +fun check_vec(v: &vector, bound: u64) { + let i = 0; + let n = vector::length(v); + while (i < n) { + let cur = *vector::borrow(v, i); + if (cur > bound) abort 42; + i = i + 1; + } +} +``` + +### `assert` + +`assert` is a builtin, macro-like operation provided by the Move compiler. It takes two arguments, a +condition of type `bool` and a code of type `u64` + +```move +assert!(condition: bool, code: u64) +``` + +Since the operation is a macro, it must be invoked with the `!`. This is to convey that the +arguments to `assert` are call-by-expression. In other words, `assert` is not a normal function and +does not exist at the bytecode level. It is replaced inside the compiler with + +```move +if (condition) () else abort code +``` + +`assert` is more commonly used than just `abort` by itself. The `abort` examples above can be +rewritten using `assert` + +```move= +use std::vector; +fun pop_twice(v: &mut vector): (T, T) { + assert!(vector::length(v) >= 2, 42); // Now uses 'assert' + + (vector::pop_back(v), vector::pop_back(v)) +} +``` + +and + +```move= +use std::vector; +fun check_vec(v: &vector, bound: u64) { + let i = 0; + let n = vector::length(v); + while (i < n) { + let cur = *vector::borrow(v, i); + assert!(cur <= bound, 42); // Now uses 'assert' + i = i + 1; + } +} +``` + +Note that because the operation is replaced with this `if-else`, the argument for the `code` is not +always evaluated. For example: + +```move +assert!(true, 1 / 0) +``` + +Will not result in an arithmetic error, it is equivalent to + +```move +if (true) () else (1 / 0) +``` + +So the arithmetic expression is never evaluated! + +### Abort codes in the Move VM + +When using `abort`, it is important to understand how the `u64` code will be used by the VM. + +Normally, after successful execution, the Move VM produces a change-set for the changes made to +global storage (added/removed resources, updates to existing resources, etc). + +If an `abort` is reached, the VM will instead indicate an error. Included in that error will be two +pieces of information: + +- The module that produced the abort (address and name) +- The abort code. + +For example + +```move= +address 0x2 { +module example { + public fun aborts() { + abort 42 + } +} +} + +script { + fun always_aborts() { + 0x2::example::aborts() + } +} +``` + +If a transaction, such as the script `always_aborts` above, calls `0x2::example::aborts`, the VM +would produce an error that indicated the module `0x2::example` and the code `42`. + +This can be useful for having multiple aborts being grouped together inside a module. + +In this example, the module has two separate error codes used in multiple functions + +```move= +address 0x42 { +module example { + + use std::vector; + + const EMPTY_VECTOR: u64 = 0; + const INDEX_OUT_OF_BOUNDS: u64 = 1; + + // move i to j, move j to k, move k to i + public fun rotate_three(v: &mut vector, i: u64, j: u64, k: u64) { + let n = vector::length(v); + assert!(n > 0, EMPTY_VECTOR); + assert!(i < n, INDEX_OUT_OF_BOUNDS); + assert!(j < n, INDEX_OUT_OF_BOUNDS); + assert!(k < n, INDEX_OUT_OF_BOUNDS); + + vector::swap(v, i, k); + vector::swap(v, j, k); + } + + public fun remove_twice(v: &mut vector, i: u64, j: u64): (T, T) { + let n = vector::length(v); + assert!(n > 0, EMPTY_VECTOR); + assert!(i < n, INDEX_OUT_OF_BOUNDS); + assert!(j < n, INDEX_OUT_OF_BOUNDS); + assert!(i > j, INDEX_OUT_OF_BOUNDS); + + (vector::remove(v, i), vector::remove(v, j)) + } +} +} +``` + +## The type of `abort` + +The `abort i` expression can have any type! This is because both constructs break from the normal +control flow, so they never need to evaluate to the value of that type. + +The following are not useful, but they will type check + +```move +let y: address = abort 0; +``` + +This behavior can be helpful in situations where you have a branching instruction that produces a +value on some branches, but not all. For example: + +```move +let b = + if (x == 0) false + else if (x == 1) true + else abort 42; +// ^^^^^^^^ `abort 42` has type `bool` +``` diff --git a/vendors/move/crates/documentation/book/src/address.md b/vendors/move/crates/documentation/book/src/address.md new file mode 100644 index 000000000..88d8b3f5e --- /dev/null +++ b/vendors/move/crates/documentation/book/src/address.md @@ -0,0 +1,73 @@ +# Address + +`address` is a built-in type in Move that is used to represent locations (sometimes called accounts) in global storage. An `address` value is a 128-bit (16 byte) identifier. At a given address, two things can be stored: [Modules](./modules-and-scripts.md) and [Resources](./structs-and-resources.md). + +Although an `address` is a 128 bit integer under the hood, Move addresses are intentionally opaque---they cannot be created from integers, they do not support arithmetic operations, and they cannot be modified. Even though there might be interesting programs that would use such a feature (e.g., pointer arithmetic in C fills a similar niche), Move does not allow this dynamic behavior because it has been designed from the ground up to support static verification. + +You can use runtime address values (values of type `address`) to access resources at that address. You *cannot* access modules at runtime via address values. + +## Addresses and Their Syntax + +Addresses come in two flavors, named or numerical. The syntax for a named address follows the +same rules for any named identifier in Move. The syntax of a numerical address is not restricted +to hex-encoded values, and any valid [`u128` numerical value](./integers.md) can be used as an +address value, e.g., `42`, `0xCAFE`, and `2021` are all valid numerical address +literals. + +To distinguish when an address is being used in an expression context or not, the +syntax when using an address differs depending on the context where it's used: +* When an address is used as an expression the address must be prefixed by the `@` character, i.e., [`@`](./integers.md) or `@`. +* Outside of expression contexts, the address may be written without the leading `@` character, i.e., [``](./integers.md) or ``. + +In general, you can think of `@` as an operator that takes an address from being a namespace item to being an expression item. + +## Named Addresses + +Named addresses are a feature that allow identifiers to be used in place of +numerical values in any spot where addresses are used, and not just at the +value level. Named addresses are declared and bound as top level elements +(outside of modules and scripts) in Move Packages, or passed as arguments +to the Move compiler. + +Named addresses only exist at the source language level and will be fully +substituted for their value at the bytecode level. Because of this, modules +and module members _must_ be accessed through the module's named address +and not through the numerical value assigned to the named address during +compilation, e.g., `use my_addr::foo` is _not_ equivalent to `use 0x2::foo` +even if the Move program is compiled with `my_addr` set to `0x2`. This +distinction is discussed in more detail in the section on [Modules and +Scripts](./modules-and-scripts.md). + +### Examples + +```move +let a1: address = @0x1; // shorthand for 0x00000000000000000000000000000001 +let a2: address = @0x42; // shorthand for 0x00000000000000000000000000000042 +let a3: address = @0xDEADBEEF; // shorthand for 0x000000000000000000000000DEADBEEF +let a4: address = @0x0000000000000000000000000000000A; +let a5: address = @std; // Assigns `a5` the value of the named address `std` +let a6: address = @66; +let a7: address = @0x42; + +module 66::some_module { // Not in expression context, so no @ needed + use 0x1::other_module; // Not in expression context so no @ needed + use std::vector; // Can use a named address as a namespace item when using other modules + ... +} + +module std::other_module { // Can use a named address as a namespace item to declare a module + ... +} +``` + +## Global Storage Operations + +The primary purpose of `address` values are to interact with the global storage operations. + +`address` values are used with the `exists`, `borrow_global`, `borrow_global_mut`, and `move_from` [operations](./global-storage-operators.md). + +The only global storage operation that *does not* use `address` is `move_to`, which uses [`signer`](./signer.md). + +## Ownership + +As with the other scalar values built-in to the language, `address` values are implicitly copyable, meaning they can be copied without an explicit instruction such as [`copy`](./variables.md#move-and-copy). diff --git a/vendors/move/crates/documentation/book/src/bool.md b/vendors/move/crates/documentation/book/src/bool.md new file mode 100644 index 000000000..6423a8c63 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/bool.md @@ -0,0 +1,33 @@ +# Bool + +`bool` is Move's primitive type for boolean `true` and `false` values. + +## Literals + +Literals for `bool` are either `true` or `false`. + +## Operations + +### Logical + +`bool` supports three logical operations: + +| Syntax | Description | Equivalent Expression | +| ------------------------- | ---------------------------- | ------------------------------------------------------------------- | +| `&&` | short-circuiting logical and | `p && q` is equivalent to `if (p) q else false` | +| || | short-circuiting logical or | p || q is equivalent to `if (p) true else q` | +| `!` | logical negation | `!p` is equivalent to `if (p) false else true` | + +### Control Flow + +`bool` values are used in several of Move's control-flow constructs: + +- [`if (bool) { ... }`](./conditionals.md) +- [`while (bool) { .. }`](./loops.md) +- [`assert!(bool, u64)`](./abort-and-assert.md) + +## Ownership + +As with the other scalar values built-in to the language, boolean values are implicitly copyable, +meaning they can be copied without an explicit instruction such as +[`copy`](./variables.md#move-and-copy). diff --git a/vendors/move/crates/documentation/book/src/coding-conventions.md b/vendors/move/crates/documentation/book/src/coding-conventions.md new file mode 100644 index 000000000..caea845e4 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/coding-conventions.md @@ -0,0 +1,77 @@ +# Move Coding Conventions + +This section lays out some basic coding conventions for Move that the Move team has found helpful. These are only recommendations, and you should feel free to use other formatting guidelines and conventions if you have a preference for them. + +## Naming + +- **Module names**: should be lower snake case, e.g., `fixed_point32`, `vector`. +- **Type names**: should be camel case if they are not a native type, e.g., `Coin`, `RoleId`. +- **Function names**: should be lower snake case, e.g., `destroy_empty`. +- **Constant names**: should be upper camel case and begin with an `E` if they represent error codes (e.g., `EIndexOutOfBounds`) and upper snake case if they represent a non-error value (e.g., `MIN_STAKE`). +- +- **Generic type names**: should be descriptive, or anti-descriptive where appropriate, e.g., `T` or `Element` for the Vector generic type parameter. Most of the time the "main" type in a module should be the same name as the module e.g., `option::Option`, `fixed_point32::FixedPoint32`. +- **Module file names**: should be the same as the module name e.g., `Option.move`. +- **Script file names**: should be lower snake case and should match the name of the “main” function in the script. +- **Mixed file names**: If the file contains multiple modules and/or scripts, the file name should be lower snake case, where the name does not match any particular module/script inside. + +## Imports + +- All module `use` statements should be at the top of the module. +- Functions should be imported and used fully qualified from the module in which they are declared, and not imported at the top level. +- Types should be imported at the top-level. Where there are name clashes, `as` should be used to rename the type locally as appropriate. + +For example, if there is a module: + +```move +module 0x1::foo { + struct Foo { } + const CONST_FOO: u64 = 0; + public fun do_foo(): Foo { Foo{} } + ... +} +``` + +this would be imported and used as: + +```move +module 0x1::bar { + use 0x1::foo::{Self, Foo}; + + public fun do_bar(x: u64): Foo { + if (x == 10) { + foo::do_foo() + } else { + abort 0 + } + } + ... +} +``` + +And, if there is a local name-clash when importing two modules: + +```move +module other_foo { + struct Foo {} + ... +} + +module 0x1::importer { + use 0x1::other_foo::Foo as OtherFoo; + use 0x1::foo::Foo; + ... +} +``` + +## Comments + +- Each module, struct, and public function declaration should be commented. +- Move has doc comments `///`, regular single-line comments `//`, block comments `/* */`, and block doc comments `/** */`. + +## Formatting + +The Move team plans to write an autoformatter to enforce formatting conventions. However, in the meantime: + +- Four space indentation should be used except for `script` and `address` blocks whose contents should not be indented. +- Lines should be broken if they are longer than 100 characters. +- Structs and constants should be declared before all functions in a module. diff --git a/vendors/move/crates/documentation/book/src/conditionals.md b/vendors/move/crates/documentation/book/src/conditionals.md new file mode 100644 index 000000000..35a7188b9 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/conditionals.md @@ -0,0 +1,61 @@ +# Conditionals + +An `if` expression specifies that some code should only be evaluated if a certain condition is true. For example: + +```move +if (x > 5) x = x - 5 +``` + +The condition must be an expression of type `bool`. + +An `if` expression can optionally include an `else` clause to specify another expression to evaluate when the condition is false. + +```move +if (y <= 10) y = y + 1 else y = 10 +``` + +Either the "true" branch or the "false" branch will be evaluated, but not both. Either branch can be a single expression or an expression block. + +The conditional expressions may produce values so that the `if` expression has a result. + +```move +let z = if (x < 100) x else 100; +``` + +The expressions in the true and false branches must have compatible types. For example: + +```move= +// x and y must be u64 integers +let maximum: u64 = if (x > y) x else y; + +// ERROR! branches different types +let z = if (maximum < 10) 10u8 else 100u64; + +// ERROR! branches different types, as default false-branch is () not u64 +if (maximum >= 10) maximum; +``` + +If the `else` clause is not specified, the false branch defaults to the unit value. The following are equivalent: + +```move +if (condition) true_branch // implied default: else () +if (condition) true_branch else () +``` + +Commonly, [`if` expressions](./conditionals.md) are used in conjunction with expression blocks. + +```move +let maximum = if (x > y) x else y; +if (maximum < 10) { + x = x + 10; + y = y + 10; +} else if (x >= 10 && y >= 10) { + x = x - 10; + y = y - 10; +} +``` + +## Grammar for Conditionals + +> *if-expression* → **if (** *expression* **)** *expression* *else-clause**opt* +> *else-clause* → **else** *expression* diff --git a/vendors/move/crates/documentation/book/src/constants.md b/vendors/move/crates/documentation/book/src/constants.md new file mode 100644 index 000000000..c59f0107c --- /dev/null +++ b/vendors/move/crates/documentation/book/src/constants.md @@ -0,0 +1,112 @@ +# Constants + +Constants are a way of giving a name to shared, static values inside of a `module` or `script`. + +The constant's must be known at compilation. The constant's value is stored in the compiled module +or script. And each time the constant is used, a new copy of that value is made. + +## Declaration + +Constant declarations begin with the `const` keyword, followed by a name, a type, and a value. They +can exist in either a script or module + +```text +const : = ; +``` + +For example + +```move= +script { + + const MY_ERROR_CODE: u64 = 0; + + fun main(input: u64) { + assert!(input > 0, MY_ERROR_CODE); + } + +} + +address 0x42 { +module example { + + const MY_ADDRESS: address = @0x42; + + public fun permissioned(s: &signer) { + assert!(std::signer::address_of(s) == MY_ADDRESS, 0); + } + +} +} +``` + +## Naming + +Constants must start with a capital letter `A` to `Z`. After the first letter, constant names can +contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, or digits `0` to `9`. + +```move +const FLAG: bool = false; +const MY_ERROR_CODE: u64 = 0; +const ADDRESS_42: address = @0x42; +``` + +Even though you can use letters `a` to `z` in a constant. The +[general style guidelines](./coding-conventions.md) are to use just uppercase letters `A` to `Z`, +with underscores `_` between each word. + +This naming restriction of starting with `A` to `Z` is in place to give room for future language +features. It may or may not be removed later. + +## Visibility + +`public` constants are not currently supported. `const` values can be used only in the declaring +module. + +## Valid Expressions + +Currently, constants are limited to the primitive types `bool`, `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, `address`, and +`vector`. Future support for other `vector` values (besides the "string"-style literals) will +come later. + +### Values + +Commonly, `const`s are assigned a simple value, or literal, of their type. For example + +```move +const MY_BOOL: bool = false; +const MY_ADDRESS: address = @0x70DD; +const BYTES: vector = b"hello world"; +const HEX_BYTES: vector = x"DEADBEEF"; +``` + +### Complex Expressions + +In addition to literals, constants can include more complex expressions, as long as the compiler is +able to reduce the expression to a value at compile time. + +Currently, equality operations, all boolean operations, all bitwise operations, and all arithmetic +operations can be used. + +```move +const RULE: bool = true && false; +const CAP: u64 = 10 * 100 + 1; +const SHIFTY: u8 = { + (1 << 1) * (1 << 2) * (1 << 3) * (1 << 4) +}; +const HALF_MAX: u128 = 340282366920938463463374607431768211455 / 2; +const REM: u256 = 57896044618658097711785492504343953926634992332820282019728792003956564819968 % 654321; +const EQUAL: bool = 1 == 1; +``` + +If the operation would result in a runtime exception, the compiler will give an error that it is +unable to generate the constant's value + +```move +const DIV_BY_ZERO: u64 = 1 / 0; // error! +const SHIFT_BY_A_LOT: u64 = 1 << 100; // error! +const NEGATIVE_U64: u64 = 0 - 1; // error! +``` + +Note that constants cannot currently refer to other constants. This feature, along with support for +other expressions, will be added in the future. diff --git a/vendors/move/crates/documentation/book/src/creating-coins.md b/vendors/move/crates/documentation/book/src/creating-coins.md new file mode 100644 index 000000000..b62b4f0d7 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/creating-coins.md @@ -0,0 +1,3 @@ +# Move Tutorial + +Please refer to the [Move Tutorial](https://github.com/move-language/move/tree/main/language/documentation/tutorial). diff --git a/vendors/move/crates/documentation/book/src/equality.md b/vendors/move/crates/documentation/book/src/equality.md new file mode 100644 index 000000000..dbabfa66c --- /dev/null +++ b/vendors/move/crates/documentation/book/src/equality.md @@ -0,0 +1,164 @@ +# Equality + +Move supports two equality operations `==` and `!=` + +## Operations + +| Syntax | Operation | Description | +| ------ | --------- | --------------------------------------------------------------------------- | +| `==` | equal | Returns `true` if the two operands have the same value, `false` otherwise | +| `!=` | not equal | Returns `true` if the two operands have different values, `false` otherwise | + +### Typing + +Both the equal (`==`) and not-equal (`!=`) operations only work if both operands are the same type + +```move +0 == 0; // `true` +1u128 == 2u128; // `false` +b"hello" != x"00"; // `true` +``` + +Equality and non-equality also work over user defined types! + +```move= +address 0x42 { +module example { + struct S has copy, drop { f: u64, s: vector } + + fun always_true(): bool { + let s = S { f: 0, s: b"" }; + // parens are not needed but added for clarity in this example + (copy s) == s + } + + fun always_false(): bool { + let s = S { f: 0, s: b"" }; + // parens are not needed but added for clarity in this example + (copy s) != s + } +} +} +``` + +If the operands have different types, there is a type checking error + +```move +1u8 == 1u128; // ERROR! +// ^^^^^ expected an argument of type 'u8' +b"" != 0; // ERROR! +// ^ expected an argument of type 'vector' +``` + +### Typing with references + +When comparing [references](./references.md), the type of the reference (immutable or mutable) does +not matter. This means that you can compare an immutable `&` reference with a mutable one `&mut` of +the same underlying type. + +```move +let i = &0; +let m = &mut 1; + +i == m; // `false` +m == i; // `false` +m == m; // `true` +i == i; // `true` +``` + +The above is equivalent to applying an explicit freeze to each mutable reference where needed + +```move +let i = &0; +let m = &mut 1; + +i == freeze(m); // `false` +freeze(m) == i; // `false` +m == m; // `true` +i == i; // `true` +``` + +But again, the underlying type must be the same type + +```move +let i = &0; +let s = &b""; + +i == s; // ERROR! +// ^ expected an argument of type '&u64' +``` + +## Restrictions + +Both `==` and `!=` consume the value when comparing them. As a result, the type system enforces that +the type must have [`drop`](./abilities.md). Recall that without the +[`drop` ability](./abilities.md), ownership must be transferred by the end of the function, and such +values can only be explicitly destroyed within their declaring module. If these were used directly +with either equality `==` or non-equality `!=`, the value would be destroyed which would break +[`drop` ability](./abilities.md) safety guarantees! + +```move= +address 0x42 { +module example { + struct Coin has store { value: u64 } + fun invalid(c1: Coin, c2: Coin) { + c1 == c2 // ERROR! +// ^^ ^^ These resources would be destroyed! + } +} +} +``` + +But, a programmer can _always_ borrow the value first instead of directly comparing the value, and +reference types have the [`drop` ability](./abilities.md). For example + +```move= +address 0x42 { +module example { + struct Coin as store { value: u64 } + fun swap_if_equal(c1: Coin, c2: Coin): (Coin, Coin) { + let are_equal = &c1 == &c2; // valid + if (are_equal) (c2, c1) else (c1, c2) + } +} +} +``` + +## Avoid Extra Copies + +While a programmer _can_ compare any value whose type has [`drop`](./abilities.md), a programmer +should often compare by reference to avoid expensive copies. + +```move= +let v1: vector = function_that_returns_vector(); +let v2: vector = function_that_returns_vector(); +assert!(copy v1 == copy v2, 42); +// ^^^^ ^^^^ +use_two_vectors(v1, v2); + +let s1: Foo = function_that_returns_large_struct(); +let s2: Foo = function_that_returns_large_struct(); +assert!(copy s1 == copy s2, 42); +// ^^^^ ^^^^ +use_two_foos(s1, s2); +``` + +This code is perfectly acceptable (assuming `Foo` has [`drop`](./abilities.md)), just not efficient. +The highlighted copies can be removed and replaced with borrows + +```move= +let v1: vector = function_that_returns_vector(); +let v2: vector = function_that_returns_vector(); +assert!(&v1 == &v2, 42); +// ^ ^ +use_two_vectors(v1, v2); + +let s1: Foo = function_that_returns_large_struct(); +let s2: Foo = function_that_returns_large_struct(); +assert!(&s1 == &s2, 42); +// ^ ^ +use_two_foos(s1, s2); +``` + +The efficiency of the `==` itself remains the same, but the `copy`s are removed and thus the program +is more efficient. diff --git a/vendors/move/crates/documentation/book/src/friends.md b/vendors/move/crates/documentation/book/src/friends.md new file mode 100644 index 000000000..1dab74fe4 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/friends.md @@ -0,0 +1,131 @@ +# Friends + +The `friend` syntax is used to declare modules that are trusted by the current module. +A trusted module is allowed to call any function defined in the current module that have the `public(friend)` visibility. +For details on function visibilities, please refer to the *Visibility* section in [Functions](./functions.md). + +## Friend declaration + +A module can declare other modules as friends via friend declaration statements, in the format of + +- `friend ` — friend declaration using fully qualified module name like the example below, or + + ```move + address 0x42 { + module a { + friend 0x42::b; + } + } + ``` + +- `friend ` — friend declaration using a module name alias, where the module alias is introduced via the `use` statement. + + ```move + address 0x42 { + module a { + use 0x42::b; + friend b; + } + } + ``` + +A module may have multiple friend declarations, and the union of all the friend modules forms the friend list. +In the example below, both `0x42::B` and `0x42::C` are considered as friends of `0x42::A`. + +```move +address 0x42 { +module a { + friend 0x42::b; + friend 0x42::c; +} +} +``` + +Unlike `use` statements, `friend` can only be declared in the module scope and not in the expression block scope. +`friend` declarations may be located anywhere a top-level construct (e.g., `use`, `function`, `struct`, etc.) is allowed. +However, for readability, it is advised to place friend declarations near the beginning of the module definition. + +Note that the concept of friendship does not apply to Move scripts: +- A Move script cannot declare `friend` modules as doing so is considered meaningless: there is no mechanism to call the function defined in a script. +- A Move module cannot declare `friend` scripts as well because scripts are ephemeral code snippets that are never published to global storage. + +### Friend declaration rules +Friend declarations are subject to the following rules: + +- A module cannot declare itself as a friend. + + ```move= + address 0x42 { + module m { friend Self; // ERROR! } + // ^^^^ Cannot declare the module itself as a friend + } + + address 0x43 { + module m { friend 0x43::M; // ERROR! } + // ^^^^^^^ Cannot declare the module itself as a friend + } + ``` + +- Friend modules must be known by the compiler + + ```move= + address 0x42 { + module m { friend 0x42::nonexistent; // ERROR! } + // ^^^^^^^^^^^^^^^^^ Unbound module '0x42::nonexistent' + } + ``` + +- Friend modules must be within the same account address. (Note: this is not a technical requirement but rather a policy decision which *may* be relaxed later.) + + ```move= + address 0x42 { + module m {} + } + + address 0x43 { + module n { friend 0x42::m; // ERROR! } + // ^^^^^^^ Cannot declare modules out of the current address as a friend + } + ``` + +- Friends relationships cannot create cyclic module dependencies. + + Cycles are not allowed in the friend relationships, e.g., the relation `0x2::a` friends `0x2::b` friends `0x2::c` friends `0x2::a` is not allowed. +More generally, declaring a friend module adds a dependency upon the current module to the friend module (because the purpose is for the friend to call functions in the current module). +If that friend module is already used, either directly or transitively, a cycle of dependencies would be created. + ```move= + address 0x2 { + module a { + use 0x2::c; + friend 0x2::b; + + public fun a() { + c::c() + } + } + + module b { + friend 0x2::c; // ERROR! + // ^^^^^^ This friend relationship creates a dependency cycle: '0x2::b' is a friend of '0x2::a' uses '0x2::c' is a friend of '0x2::b' + } + + module c { + public fun c() {} + } + } + ``` + +- The friend list for a module cannot contain duplicates. + + ```move= + address 0x42 { + module a {} + + module m { + use 0x42::a as aliased_a; + friend 0x42::A; + friend aliased_a; // ERROR! + // ^^^^^^^^^ Duplicate friend declaration '0x42::a'. Friend declarations in a module must be unique + } + } + ``` diff --git a/vendors/move/crates/documentation/book/src/functions.md b/vendors/move/crates/documentation/book/src/functions.md new file mode 100644 index 000000000..e95d533ff --- /dev/null +++ b/vendors/move/crates/documentation/book/src/functions.md @@ -0,0 +1,560 @@ +# Functions + +Function syntax in Move is shared between module functions and script functions. Functions inside of modules are reusable, whereas script functions are only used once to invoke a transaction. + +## Declaration + +Functions are declared with the `fun` keyword followed by the function name, type parameters, parameters, a return type, acquires annotations, and finally the function body. + +```text +fun <[type_parameters: constraint],*>([identifier: type],*): +``` + +For example + +```move +fun foo(x: u64, y: T1, z: T2): (T2, T1, u64) { (z, y, x) } +``` + +### Visibility + +Module functions, by default, can only be called within the same module. These internal (sometimes called private) functions cannot be called from other modules or from scripts. + +```move= +address 0x42 { +module m { + fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid +} + +module other { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } +} +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } +} +``` + +To allow access from other modules or from scripts, the function must be declared `public` or `public(friend)`. + +#### `public` visibility + +A `public` function can be called by *any* function defined in *any* module or script. As shown in the following example, a `public` function can be called by: +- other functions defined in the same module, +- functions defined in another module, or +- the function defined in a script. + +There are also no restrictions for what the argument types a public function can take and its return type. + +```move= +address 0x42 { +module m { + public fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid +} + +module other { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid + } +} +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid + } +} +``` + +#### `public(friend)` visibility + +The `public(friend)` visibility modifier is a more restricted form of the `public` modifier to give more control about where a function can be used. A `public(friend)` function can be called by: +- other functions defined in the same module, or +- functions defined in modules which are explicitly specified in the **friend list** (see [Friends](./friends.md) on how to specify the friend list). + +Note that since we cannot declare a script to be a friend of a module, the functions defined in scripts can never call a `public(friend)` function. + +```move= +address 0x42 { +module m { + friend 0x42::n; // friend declaration + public(friend) fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid +} + +module n { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid + } +} + +module other { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' can only be called from a 'friend' of module '0x42::m' + } +} +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' can only be called from a 'friend' of module '0x42::m' + } +} +``` + +### `entry` modifier + +The `entry` modifier is designed to allow module functions to be safely and directly invoked much like scripts. This allows module writers to specify which functions can be to begin execution. The module writer then knows that any non-`entry` function will be called from a Move program already in execution. + +Essentially, `entry` functions are the "main" functions of a module, and they specify where Move programs start executing. + +Note though, an `entry` function _can_ still be called by other Move functions. So while they _can_ serve as the start of a Move program, they aren't restricted to that case. + +For example: + +```move= +address 0x42 { +module m { + public entry fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid! +} + +module n { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid! + } +} + +module other { + public entry fun calls_m_foo(): u64 { + 0x42::m::foo() // valid! + } +} +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid! + } +} +``` + +Even internal functions can be marked as `entry`! This lets you guarantee that the function is called only at the beginning of execution (assuming you do not call it elsewhere in your module) + +```move= +address 0x42 { +module m { + entry fun foo(): u64 { 0 } // valid! entry functions do not have to be public +} + +module n { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } +} + +module other { + public entry fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } +} +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } +} +``` + +Entry functions can take primitive types, String, and vector arguments but cannot take Structs (e.g. Option). They also +must not have any return values. + +### Name + +Function names can start with letters `a` to `z` or letters `A` to `Z`. After the first character, function names can contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, or digits `0` to `9`. + +```move +fun FOO() {} +fun bar_42() {} +fun _bAZ19() {} +``` + +### Type Parameters + +After the name, functions can have type parameters + +```move +fun id(x: T): T { x } +fun example(x: T1, y: T2): (T1, T1, T2) { (copy x, x, y) } +``` + +For more details, see [Move generics](./generics.md). + +### Parameters + +Functions parameters are declared with a local variable name followed by a type annotation + +```move +fun add(x: u64, y: u64): u64 { x + y } +``` + +We read this as `x` has type `u64` + +A function does not have to have any parameters at all. + +```move +fun useless() { } +``` + +This is very common for functions that create new or empty data structures + +```move= +address 0x42 { +module example { + struct Counter { count: u64 } + + fun new_counter(): Counter { + Counter { count: 0 } + } + +} +} +``` + +### Acquires + +When a function accesses a resource using `move_from`, `borrow_global`, or `borrow_global_mut`, the function must indicate that it `acquires` that resource. This is then used by Move's type system to ensure the references into global storage are safe, specifically that there are no dangling references into global storage. + +```move= +address 0x42 { +module example { + + struct Balance has key { value: u64 } + + public fun add_balance(s: &signer, value: u64) { + move_to(s, Balance { value }) + } + + public fun extract_balance(addr: address): u64 acquires Balance { + let Balance { value } = move_from(addr); // acquires needed + value + } +} +} +``` + +`acquires` annotations must also be added for transitive calls within the module. Calls to these functions from another module do not need to annotated with these acquires because one module cannot access resources declared in another module--so the annotation is not needed to ensure reference safety. + +```move= +address 0x42 { +module example { + + struct Balance has key { value: u64 } + + public fun add_balance(s: &signer, value: u64) { + move_to(s, Balance { value }) + } + + public fun extract_balance(addr: address): u64 acquires Balance { + let Balance { value } = move_from(addr); // acquires needed + value + } + + public fun extract_and_add(sender: address, receiver: &signer) acquires Balance { + let value = extract_balance(sender); // acquires needed here + add_balance(receiver, value) + } +} +} + +address 0x42 { +module other { + fun extract_balance(addr: address): u64 { + 0x42::example::extract_balance(addr) // no acquires needed + } +} +} +``` + +A function can `acquire` as many resources as it needs to + +```move= +address 0x42 { +module example { + use std::vector; + + struct Balance has key { value: u64 } + struct Box has key { items: vector } + + public fun store_two( + addr: address, + item1: Item1, + item2: Item2, + ) acquires Balance, Box { + let balance = borrow_global_mut(addr); // acquires needed + balance.value = balance.value - 2; + let box1 = borrow_global_mut>(addr); // acquires needed + vector::push_back(&mut box1.items, item1); + let box2 = borrow_global_mut>(addr); // acquires needed + vector::push_back(&mut box2.items, item2); + } +} +} +``` + +### Return type + +After the parameters, a function specifies its return type. + +```move +fun zero(): u64 { 0 } +``` + +Here `: u64` indicates that the function's return type is `u64`. + +Using tuples, a function can return multiple values: + +```move +fun one_two_three(): (u64, u64, u64) { (0, 1, 2) } +``` + +If no return type is specified, the function has an implicit return type of unit `()`. These functions are equivalent: + +```move +fun just_unit(): () { () } +fun just_unit() { () } +fun just_unit() { } +``` + +`script` functions must have a return type of unit `()`: + +```move +script { + fun do_nothing() { + } +} +``` + +As mentioned in the [tuples section](./tuples.md), these tuple "values" are virtual and do not exist at runtime. So for a function that returns unit `()`, it will not be returning any value at all during execution. + +### Function body + +A function's body is an expression block. The return value of the function is the last value in the sequence + +```move= +fun example(): u64 { + let x = 0; + x = x + 1; + x // returns 'x' +} +``` + +See [the section below for more information on returns](#returning-values) + +For more information on expression blocks, see [Move variables](./variables.md). + +### Native Functions + +Some functions do not have a body specified, and instead have the body provided by the VM. These functions are marked `native`. + +Without modifying the VM source code, a programmer cannot add new native functions. Furthermore, it is the intent that `native` functions are used for either standard library code or for functionality needed for the given Move environment. + +Most `native` functions you will likely see are in standard library code such as `vector` + +```move= +module std::vector { + native public fun empty(): vector; + ... +} +``` + +## Calling + +When calling a function, the name can be specified either through an alias or fully qualified + +```move= +address 0x42 { +module example { + public fun zero(): u64 { 0 } +} +} + +script { + use 0x42::example::{Self, zero}; + fun call_zero() { + // With the `use` above all of these calls are equivalent + 0x42::example::zero(); + example::zero(); + zero(); + } +} +``` + +When calling a function, an argument must be given for every parameter. + +```move= +address 0x42 { +module example { + public fun takes_none(): u64 { 0 } + public fun takes_one(x: u64): u64 { x } + public fun takes_two(x: u64, y: u64): u64 { x + y } + public fun takes_three(x: u64, y: u64, z: u64): u64 { x + y + z } +} +} + +script { + use 0x42::example; + fun call_all() { + example::takes_none(); + example::takes_one(0); + example::takes_two(0, 1); + example::takes_three(0, 1, 2); + } +} +``` + +Type arguments can be either specified or inferred. Both calls are equivalent. + +```move= +address 0x42 { +module example { + public fun id(x: T): T { x } +} +} + +script { + use 0x42::example; + fun call_all() { + example::id(0); + example::id(0); + } +} +``` + +For more details, see [Move generics](./generics.md). + + +## Returning values + +The result of a function, its "return value", is the final value of its function body. For example + +```move= +fun add(x: u64, y: u64): u64 { + x + y +} +``` + +[As mentioned above](#function-body), the function's body is an [expression block](./variables.md). The expression block can sequence various statements, and the final expression in the block will be be the value of that block + +```move= +fun double_and_add(x: u64, y: u64): u64 { + let double_x = x * 2; + let double_y = y * 2; + double_x + double_y +} +``` + +The return value here is `double_x + double_y` + +### `return` expression + +A function implicitly returns the value that its body evaluates to. However, functions can also use the explicit `return` expression: + +```move +fun f1(): u64 { return 0 } +fun f2(): u64 { 0 } +``` + +These two functions are equivalent. In this slightly more involved example, the function subtracts two `u64` values, but returns early with `0` if the second value is too large: + +```move= +fun safe_sub(x: u64, y: u64): u64 { + if (y > x) return 0; + x - y +} +``` + +Note that the body of this function could also have been written as `if (y > x) 0 else x - y`. + +However `return` really shines is in exiting deep within other control flow constructs. In this example, the function iterates through a vector to find the index of a given value: + +```move= +use std::vector; +use std::option::{Self, Option}; +fun index_of(v: &vector, target: &T): Option { + let i = 0; + let n = vector::length(v); + while (i < n) { + if (vector::borrow(v, i) == target) return option::some(i); + i = i + 1 + }; + + option::none() +} +``` + +Using `return` without an argument is shorthand for `return ()`. That is, the following two functions are equivalent: + +```move +fun foo() { return } +fun foo() { return () } +``` + +## Inline Functions + +Inline functions are functions which are expanded at caller side instead +of compiled into Move bytecode. This allows to safe gas and may lead +to faster execution. For example, one can define an inline function + +```move= +inline fun percent(x: u64, y: u64):u64 { x * 100 / y } +``` + +Now, when call `percent(2, 200)` the compiler will inline the function +definition as if the user has written `2 * 100 / 200`. + +### Function Parameters + +Inline functions support _function parameters_. This allows +to define higher-order functions in Move which can comprehend common +programming patterns. As inline functions are expanded at compilation time, +this feature of function parameters can be supported without direct +support for it in Move bytecode. + +Consider the following function (from the `vector` module): + +```move= +/// Fold the function over the elements. For example, `fold(vector[1,2,3], 0, f)` will execute +/// `f(f(f(0, 1), 2), 3)` +public inline fun fold( + v: vector, + init: Accumulator, + f: |Accumulator,Element|Accumulator +): Accumulator { + let accu = init; + foreach(v, |elem| accu = g(accu, elem)); + accu +} +``` + +Here, `foreach` is itself an inline function. + +In general, only lambda expressions can be passed to function parameters. +Similar as the inline function itself, those lambdas are expanded at caller +side. Notice that a lambda can access variables in the context, as in the +example the variable `accu`. diff --git a/vendors/move/crates/documentation/book/src/generics.md b/vendors/move/crates/documentation/book/src/generics.md new file mode 100644 index 000000000..d7f0d437a --- /dev/null +++ b/vendors/move/crates/documentation/book/src/generics.md @@ -0,0 +1,482 @@ +# Generics + +Generics can be used to define functions and structs over different input data types. This language feature is sometimes referred to as *parametric polymorphism*. In Move, we will often use the term generics interchangeably with type parameters and type arguments. + +Generics are commonly used in library code, such as in vector, to declare code that works over any possible instantiation (that satisfies the specified constraints). In other frameworks, generic code can sometimes be used to interact with global storage many different ways that all still share the same implementation. + +## Declaring Type Parameters + +Both functions and structs can take a list of type parameters in their signatures, enclosed by a pair of angle brackets `<...>`. + +### Generic Functions + +Type parameters for functions are placed after the function name and before the (value) parameter list. The following code defines a generic identity function that takes a value of any type and returns that value unchanged. + +```move +fun id(x: T): T { + // this type annotation is unnecessary but valid + (x: T) +} +``` + +Once defined, the type parameter `T` can be used in parameter types, return types, and inside the function body. + +### Generic Structs + +Type parameters for structs are placed after the struct name, and can be used to name the types of the fields. + +```move +struct Foo has copy, drop { x: T } + +struct Bar has copy, drop { + x: T1, + y: vector, +} +``` + +Note that [type parameters do not have to be used](#unused-type-parameters) + +## Type Arguments + +### Calling Generic Functions + +When calling a generic function, one can specify the type arguments for the function's type parameters in a list enclosed by a pair of angle brackets. + +```move +fun foo() { + let x = id(true); +} +``` + +If you do not specify the type arguments, Move's [type inference](#type-inference) will supply them for you. + +### Using Generic Structs + +Similarly, one can attach a list of type arguments for the struct's type parameters when constructing or destructing values of generic types. + +```move +fun foo() { + let foo = Foo { x: true }; + let Foo { x } = foo; +} +``` + +If you do not specify the type arguments, Move's [type inference](#type-inference) will supply them for you. + +### Type Argument Mismatch + +If you specify the type arguments and they conflict with the actual values supplied, an error will be given: + +```move +fun foo() { + let x = id(true); // error! true is not a u64 +} +``` + +and similarly: + +```move +fun foo() { + let foo = Foo { x: 0 }; // error! 0 is not a bool + let Foo
{ x } = foo; // error! bool is incompatible with address +} +``` + +## Type Inference + +In most cases, the Move compiler will be able to infer the type arguments so you don't have to write them down explicitly. Here's what the examples above would look like if we omit the type arguments: + +```move +fun foo() { + let x = id(true); + // ^ is inferred + + let foo = Foo { x: true }; + // ^ is inferred + + let Foo { x } = foo; + // ^ is inferred +} +``` + +Note: when the compiler is unable to infer the types, you'll need annotate them manually. A common scenario is to call a function with type parameters appearing only at return positions. + +```move +address 0x2 { +module m { + using std::vector; + + fun foo() { + // let v = vector::new(); + // ^ The compiler cannot figure out the element type. + + let v = vector::new(); + // ^~~~~ Must annotate manually. + } +} +} +``` + +However, the compiler will be able to infer the type if that return value is used later in that function: + +```move +address 0x2 { +module m { + using std::vector; + + fun foo() { + let v = vector::new(); + // ^ is inferred + vector::push_back(&mut v, 42); + } +} +} +``` + +## Unused Type Parameters + +For a struct definition, +an unused type parameter is one that +does not appear in any field defined in the struct, +but is checked statically at compile time. +Move allows unused type parameters so the following struct definition is valid: + +```move +struct Foo { + foo: u64 +} +``` + +This can be convenient when modeling certain concepts. Here is an example: + +```move +address 0x2 { +module m { + // Currency Specifiers + struct Currency1 {} + struct Currency2 {} + + // A generic coin type that can be instantiated using a currency + // specifier type. + // e.g. Coin, Coin etc. + struct Coin has store { + value: u64 + } + + // Write code generically about all currencies + public fun mint_generic(value: u64): Coin { + Coin { value } + } + + // Write code concretely about one currency + public fun mint_concrete(value: u64): Coin { + Coin { value } + } +} +} +``` + +In this example, +`struct Coin` is generic on the `Currency` type parameter, +which specifies the currency of the coin and +allows code to be written either +generically on any currency or +concretely on a specific currency. +This genericity applies even when the `Currency` type parameter +does not appear in any of the fields defined in `Coin`. + +### Phantom Type Parameters + +In the example above, +although `struct Coin` asks for the `store` ability, +neither `Coin` nor `Coin` will have the `store` ability. +This is because of the rules for +[Conditional Abilities and Generic Types](./abilities.md#conditional-abilities-and-generic-types) +and the fact that `Currency1` and `Currency2` don't have the `store` ability, +despite the fact that they are not even used in the body of `struct Coin`. +This might cause some unpleasant consequences. +For example, we are unable to put `Coin` into a wallet in the global storage. + +One possible solution would be to +add spurious ability annotations to `Currency1` and `Currency2` +(i.e., `struct Currency1 has store {}`). +But, this might lead to bugs or security vulnerabilities +because it weakens the types with unnecessary ability declarations. +For example, we would never expect a resource in the global storage to have a field in type `Currency1`, +but this would be possible with the spurious `store` ability. +Moreover, the spurious annotations would be infectious, +requiring many functions generic on the unused type parameter to also include the necessary constraints. + +Phantom type parameters solve this problem. +Unused type parameters can be marked as *phantom* type parameters, +which do not participate in the ability derivation for structs. +In this way, +arguments to phantom type parameters are not considered when deriving the abilities for generic types, +thus avoiding the need for spurious ability annotations. +For this relaxed rule to be sound, +Move's type system guarantees that a parameter declared as `phantom` is either +not used at all in the struct definition, or +it is only used as an argument to type parameters also declared as `phantom`. + +#### Declaration + +In a struct definition +a type parameter can be declared as phantom by adding the `phantom` keyword before its declaration. +If a type parameter is declared as phantom we say it is a phantom type parameter. +When defining a struct, Move's type checker ensures that every phantom type parameter is either +not used inside the struct definition or +it is only used as an argument to a phantom type parameter. + +More formally, +if a type is used as an argument to a phantom type parameter +we say the type appears in _phantom position_. +With this definition in place, +the rule for the correct use of phantom parameters can be specified as follows: +**A phantom type parameter can only appear in phantom position**. + +The following two examples show valid uses of phantom parameters. +In the first one, +the parameter `T1` is not used at all inside the struct definition. +In the second one, the parameter `T1` is only used as an argument to a phantom type parameter. + +```move +struct S1 { f: u64 } + ^^ + Ok: T1 does not appear inside the struct definition + + +struct S2 { f: S1 } + ^^ + Ok: T1 appears in phantom position +``` + +The following code shows examples of violations of the rule: + +```move +struct S1 { f: T } + ^ + Error: Not a phantom position + +struct S2 { f: T } + +struct S3 { f: S2 } + ^ + Error: Not a phantom position +``` + +#### Instantiation + +When instantiating a struct, +the arguments to phantom parameters are excluded when deriving the struct abilities. +For example, consider the following code: + +```move +struct S has copy { f: T1 } +struct NoCopy {} +struct HasCopy has copy {} +``` + +Consider now the type `S`. +Since `S` is defined with `copy` and all non-phantom arguments have `copy` +then `S` also has `copy`. + +#### Phantom Type Parameters with Ability Constraints + +Ability constraints and phantom type parameters are orthogonal features in the sense that +phantom parameters can be declared with ability constraints. +When instantiating a phantom type parameter with an ability constraint, +the type argument has to satisfy that constraint, +even though the parameter is phantom. +For example, the following definition is perfectly valid: + +```move +struct S {} +``` + +The usual restrictions apply and `T` can only be instantiated with arguments having `copy`. + +## Constraints + +In the examples above, we have demonstrated how one can use type parameters to define "unknown" types that can be plugged in by callers at a later time. This however means the type system has little information about the type and has to perform checks in a very conservative way. In some sense, the type system must assume the worst case scenario for an unconstrained generic. Simply put, by default generic type parameters have no [abilities](./abilities.md). + +This is where constraints come into play: they offer a way to specify what properties these unknown types have so the type system can allow operations that would otherwise be unsafe. + +### Declaring Constraints + +Constraints can be imposed on type parameters using the following syntax. + +```move +// T is the name of the type parameter +T: (+ )* +``` + +The `` can be any of the four [abilities](./abilities.md), and a type parameter can be constrained with multiple abilities at once. So all of the following would be valid type parameter declarations: + +```move +T: copy +T: copy + drop +T: copy + drop + store + key +``` + +### Verifying Constraints + +Constraints are checked at call sites so the following code won't compile. + +```move +struct Foo { x: T } + +struct Bar { x: Foo } +// ^ error! u8 does not have 'key' + +struct Baz { x: Foo } +// ^ error! T does not have 'key' +``` + +```move +struct R {} + +fun unsafe_consume(x: T) { + // error! x does not have 'drop' +} + +fun consume(x: T) { + // valid! + // x will be dropped automatically +} + +fun foo() { + let r = R {}; + consume(r); + // ^ error! R does not have 'drop' +} +``` + +```move +struct R {} + +fun unsafe_double(x: T) { + (copy x, x) + // error! x does not have 'copy' +} + +fun double(x: T) { + (copy x, x) // valid! +} + +fun foo(): (R, R) { + let r = R {}; + double(r) + // ^ error! R does not have 'copy' +} +``` + +For more information, see the abilities section on [conditional abilities and generic types](./abilities.md#conditional-abilities-and-generic-types). + +## Limitations on Recursions + +### Recursive Structs + +Generic structs can not contain fields of the same type, either directly or indirectly, even with different type arguments. All of the following struct definitions are invalid: + +```move +struct Foo { + x: Foo // error! 'Foo' containing 'Foo' +} + +struct Bar { + x: Bar // error! 'Bar' containing 'Bar' +} + +// error! 'A' and 'B' forming a cycle, which is not allowed either. +struct A { + x: B +} + +struct B { + x: A + y: A +} +``` + +### Advanced Topic: Type-level Recursions + +Move allows generic functions to be called recursively. However, when used in combination with generic structs, this could create an infinite number of types in certain cases, and allowing this means adding unnecessary complexity to the compiler, vm and other language components. Therefore, such recursions are forbidden. + +Allowed: + +```move +address 0x2 { +module m { + struct A {} + + // Finitely many types -- allowed. + // foo -> foo -> foo -> ... is valid + fun foo() { + foo(); + } + + // Finitely many types -- allowed. + // foo -> foo> -> foo> -> ... is valid + fun foo() { + foo>(); + } +} +} +``` + +Not allowed: + +```move +address 0x2 { +module m { + struct A {} + + // Infinitely many types -- NOT allowed. + // error! + // foo -> foo> -> foo>> -> ... + fun foo() { + foo>(); + } +} +} +``` + +```move +address 0x2 { +module n { + struct A {} + + // Infinitely many types -- NOT allowed. + // error! + // foo -> bar -> foo> + // -> bar, T2> -> foo, A> + // -> bar, A> -> foo, A>> + // -> ... + fun foo() { + bar(); + } + + fun bar { + foo>(); + } +} +} +``` + +Note, the check for type level recursions is based on a conservative analysis on the call sites and does NOT take control flow or runtime values into account. + +```move +address 0x2 { +module m { + struct A {} + + fun foo(n: u64) { + if (n > 0) { + foo>(n - 1); + }; + } +} +} +``` + +The function in the example above will technically terminate for any given input and therefore only creating finitely many types, but it is still considered invalid by Move's type system. diff --git a/vendors/move/crates/documentation/book/src/global-storage-operators.md b/vendors/move/crates/documentation/book/src/global-storage-operators.md new file mode 100644 index 000000000..19fd9d4f9 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/global-storage-operators.md @@ -0,0 +1,250 @@ +# Global Storage - Operators + +Move programs can create, delete, and update [resources](./structs-and-resources.md) in global storage using the following five instructions: + + +| Operation | Description | Aborts? | +---------------------------------------- |---------------------------------------------------------------- |---------------------------------------- | +|`move_to(&signer,T)` | Publish `T` under `signer.address` | If `signer.address` already holds a `T` | +|`move_from(address): T` | Remove `T` from `address` and return it | If `address` does not hold a `T` | +|`borrow_global_mut(address): &mut T` | Return a mutable reference to the `T` stored under `address` | If `address` does not hold a `T` | +|`borrow_global(address): &T` | Return an immutable reference to the `T` stored under `address` | If `address` does not hold a `T` | +|`exists(address): bool` | Return `true` if a `T` is stored under `address` | Never | + + +Each of these instructions is parameterized by a type `T` with the [`key` ability](./abilities.md). However, each type `T` *must be declared in the current module*. This ensures that a resource can only be manipulated via the API exposed by its defining module. The instructions also take either an [`address`](./address.md) or [`&signer`](./signer.md) representing the account address where the resource of type `T` is stored. + +## References to resources + +References to global resources returned by `borrow_global` or `borrow_global_mut` mostly behave like references to local storage: they can be extended, read, and written using ordinary [reference operators](./references.md) and passed as arguments to other function. However, there is one important difference between local and global references: **a function cannot return a reference that points into global storage**. For example, these two functions will each fail to compile: + +```move +struct R has key { f: u64 } +// will not compile +fun ret_direct_resource_ref_bad(a: address): &R { + borrow_global(a) // error! +} +// also will not compile +fun ret_resource_field_ref_bad(a: address): &u64 { + &borrow_global(a).f // error! +} +``` + +Move must enforce this restriction to guarantee absence of dangling references to global storage. [This](#reference-safety-for-global-resources) section contains much more detail for the interested reader. + +## Global storage operators with generics + +Global storage operations can be applied to generic resources with both instantiated and uninstantiated generic type parameters: + +```move +struct Container has key { t: T } + +// Publish a Container storing a type T of the caller's choosing +fun publish_generic_container(account: &signer, t: T) { + move_to>(account, Container { t }) +} + +/// Publish a container storing a u64 +fun publish_instantiated_generic_container(account: &signer, t: u64) { + move_to>(account, Container { t }) +} +``` + +The ability to index into global storage via a type parameter chosen at runtime is a powerful Move feature known as *storage polymorphism*. For more on the design patterns enabled by this feature, see [Move generics](./generics.md). + +## Example: `Counter` + +The simple `Counter` module below exercises each of the five global storage operators. The API exposed by this module allows: + +- Anyone to publish a `Counter` resource under their account +- Anyone to check if a `Counter` exists under any address +- Anyone to read or increment the value of a `Counter` resource under any address +- An account that stores a `Counter` resource to reset it to zero +- An account that stores a `Counter` resource to remove and delete it + +```move +address 0x42 { +module counter { + use std::signer; + + /// Resource that wraps an integer counter + struct Counter has key { i: u64 } + + /// Publish a `Counter` resource with value `i` under the given `account` + public fun publish(account: &signer, i: u64) { + // "Pack" (create) a Counter resource. This is a privileged operation that + // can only be done inside the module that declares the `Counter` resource + move_to(account, Counter { i }) + } + + /// Read the value in the `Counter` resource stored at `addr` + public fun get_count(addr: address): u64 acquires Counter { + borrow_global(addr).i + } + + /// Increment the value of `addr`'s `Counter` resource + public fun increment(addr: address) acquires Counter { + let c_ref = &mut borrow_global_mut(addr).i; + *c_ref = *c_ref + 1 + } + + /// Reset the value of `account`'s `Counter` to 0 + public fun reset(account: &signer) acquires Counter { + let c_ref = &mut borrow_global_mut(signer::address_of(account)).i; + *c_ref = 0 + } + + /// Delete the `Counter` resource under `account` and return its value + public fun delete(account: &signer): u64 acquires Counter { + // remove the Counter resource + let c = move_from(signer::address_of(account)); + // "Unpack" the `Counter` resource into its fields. This is a + // privileged operation that can only be done inside the module + // that declares the `Counter` resource + let Counter { i } = c; + i + } + + /// Return `true` if `addr` contains a `Counter` resource + public fun exists(addr: address): bool { + exists(addr) + } +} +} +``` + +## Annotating functions with `acquires` + +In the `counter` example, you might have noticed that the `get_count`, `increment`, `reset`, and `delete` functions are annotated with `acquires Counter`. A Move function `m::f` must be annotated with `acquires T` if and only if: + +- The body of `m::f` contains a `move_from`, `borrow_global_mut`, or `borrow_global` instruction, or +- The body of `m::f` invokes a function `m::g` declared in the same module that is annotated with `acquires` + +For example, the following function inside `Counter` would need an `acquires` annotation: + +```move +// Needs `acquires` because `increment` is annotated with `acquires` +fun call_increment(addr: address): u64 acquires Counter { + counter::increment(addr) +} +``` + +However, the same function *outside* `Counter` would not need an annotation: + +```move +address 0x43 { +module m { + use 0x42::counter; + + // Ok. Only need annotation when resource acquired by callee is declared + // in the same module + fun call_increment(addr: address): u64 { + counter::increment(addr) + } +} +} +``` + +If a function touches multiple resources, it needs multiple `acquires`: + +```move= +address 0x42 { +module two_resources { + struct R1 has key { f: u64 } + struct R2 has key { g: u64 } + + fun double_acquires(a: address): u64 acquires R1, R2 { + borrow_global(a).f + borrow_global.g + } +} +} +``` + +The `acquires` annotation does not take generic type parameters into account: + +```move= +address 0x42 { +module m { + struct R has key { t: T } + + // `acquires R`, not `acquires R` + fun acquire_generic_resource(a: addr) acquires R { + let _ = borrow_global>(a); + } + + // `acquires R`, not `acquires R + fun acquire_instantiated_generic_resource(a: addr) acquires R { + let _ = borrow_global>(a); + } +} +} +``` + +Finally: redundant `acquires` are not allowed. Adding this function inside `Counter` will result in a compilation error: + +```move +// This code will not compile because the body of the function does not use a global +// storage instruction or invoke a function with `acquires` +fun redundant_acquires_bad() acquires Counter {} +``` + +For more information on `acquires`, see [Move functions](./functions.md). + +## Reference Safety For Global Resources + +Move prohibits returning global references and requires the `acquires` annotation to prevent dangling references. This allows Move to live up to its promise of static reference safety (i.e., no dangling references, no `null` or `nil` dereferences) for all [reference](./references.md) types. + +This example illustrates how the Move type system uses `acquires` to prevent a dangling reference: + +```move= +address 0x42 { +module dangling { + struct T has key { f: u64 } + + fun borrow_then_remove_bad(a: address) acquires T { + let t_ref: &mut T = borrow_global_mut(a); + let t = remove_t(a); // type system complains here + // t_ref now dangling! + let uh_oh = *&t_ref.f + } + + fun remove_t(a: address): T acquires T { + move_from(a) + } + +} +} +``` + +In this code, line 6 acquires a reference to the `T` stored at address `a` in global storage. The callee `remove_t` then removes the value, which makes `t_ref` a dangling reference. + +Fortunately, this cannot happen because the type system will reject this program. The `acquires` annotation on `remove_t` lets the type system know that line 7 is dangerous, without having to recheck or introspect the body of `remove_t` separately! + +The restriction on returning global references prevents a similar, but even more insidious problem: + +```move= +address 0x42 { +module m1 { + struct T has key {} + + public fun ret_t_ref(a: address): &T acquires T { + borrow_global(a) // error! type system complains here + } + + public fun remove_t(a: address) acquires T { + let T {} = move_from(a); + } +} + +module m2 { + fun borrow_then_remove_bad(a: address) { + let t_ref = m1::ret_t_ref(a); + let t = m1::remove_t(a); // t_ref now dangling! + } +} +} +``` + +Line 16 acquires a reference to a global resource `m1::T`, then line 17 removes that same resource, which makes `t_ref` dangle. In this case, `acquires` annotations do not help us because the `borrow_then_remove_bad` function is outside of the `m1` module that declares `T` (recall that `acquires` annotations can only be used for resources declared in the current module). Instead, the type system avoids this problem by preventing the return of a global reference at line 6. + +Fancier type systems that would allow returning global references without sacrificing reference safety are possible, and we may consider them in future iterations of Move. We chose the current design because it strikes a good balance between expressivity, annotation burden, and type system complexity. diff --git a/vendors/move/crates/documentation/book/src/global-storage-structure.md b/vendors/move/crates/documentation/book/src/global-storage-structure.md new file mode 100644 index 000000000..dc624e60c --- /dev/null +++ b/vendors/move/crates/documentation/book/src/global-storage-structure.md @@ -0,0 +1,14 @@ +# Global Storage - Structure + +The purpose of Move programs is to [read from and write to](./global-storage-operators.md) tree-shaped persistent global storage. Programs cannot access the filesystem, network, or any other data outside of this tree. + +In pseudocode, the global storage looks something like: + +```move +struct GlobalStorage { + resources: Map<(address, ResourceType), ResourceValue> + modules: Map<(address, ModuleName), ModuleBytecode> +} +``` + +Structurally, global storage is a [forest](https://en.wikipedia.org/wiki/Tree_(graph_theory)) consisting of trees rooted at an account [`address`](./address.md). Each address can store both [resource](./structs-and-resources.md) data values and [module](./modules-and-scripts.md) code values. As the pseudocode above indicates, each `address` can store at most one resource value of a given type and at most one module with a given name. diff --git a/vendors/move/crates/documentation/book/src/integers.md b/vendors/move/crates/documentation/book/src/integers.md new file mode 100644 index 000000000..4864d2eff --- /dev/null +++ b/vendors/move/crates/documentation/book/src/integers.md @@ -0,0 +1,153 @@ +# Integers + +Move supports six unsigned integer types: `u8`, `u16`, `u32`, `u64`, `u128`, and `u256`. Values of these types range from 0 to a maximum that depends on the size of the type. + +| Type | Value Range | +| -------------------------------- | ------------------------ | +| Unsigned 8-bit integer, `u8` | 0 to 28 - 1 | +| Unsigned 16-bit integer, `u16` | 0 to 216 - 1 | +| Unsigned 32-bit integer, `u32` | 0 to 232 - 1 | +| Unsigned 64-bit integer, `u64` | 0 to 264 - 1 | +| Unsigned 128-bit integer, `u128` | 0 to 2128 - 1 | +| Unsigned 256-bit integer, `u256` | 0 to 2256 - 1 | + +## Literals + +Literal values for these types are specified either as a sequence of digits (e.g.,`112`) or as hex literals, e.g., `0xFF`. The type of the literal can optionally be added as a suffix, e.g., `112u8`. If the type is not specified, the compiler will try to infer the type from the context where the literal is used. If the type cannot be inferred, it is assumed to be `u64`. + +Number literals can be separated by underscores for grouping and readability. (e.g.,`1_234_5678`, `1_000u128`, `0xAB_CD_12_35`). + +If a literal is too large for its specified (or inferred) size range, an error is reported. + +### Examples + +```move +// literals with explicit annotations; +let explicit_u8 = 1u8; +let explicit_u16 = 1u16; +let explicit_u32 = 1u32; +let explicit_u64 = 2u64; +let explicit_u128 = 3u128; +let explicit_u256 = 1u256; +let explicit_u64_underscored = 154_322_973u64; + +// literals with simple inference +let simple_u8: u8 = 1; +let simple_u16: u16 = 1; +let simple_u32: u32 = 1; +let simple_u64: u64 = 2; +let simple_u128: u128 = 3; +let simple_u256: u256 = 1; + +// literals with more complex inference +let complex_u8 = 1; // inferred: u8 +// right hand argument to shift must be u8 +let _unused = 10 << complex_u8; + +let x: u8 = 38; +let complex_u8 = 2; // inferred: u8 +// arguments to `+` must have the same type +let _unused = x + complex_u8; + +let complex_u128 = 133_876; // inferred: u128 +// inferred from function argument type +function_that_takes_u128(complex_u128); + +// literals can be written in hex +let hex_u8: u8 = 0x1; +let hex_u16: u16 = 0x1BAE; +let hex_u32: u32 = 0xDEAD80; +let hex_u64: u64 = 0xCAFE; +let hex_u128: u128 = 0xDEADBEEF; +let hex_u256: u256 = 0x1123_456A_BCDE_F; +``` + +## Operations + +### Arithmetic + +Each of these types supports the same set of checked arithmetic operations. For all of these operations, both arguments (the left and right side operands) *must* be of the same type. If you need to operate over values of different types, you will need to first perform a [cast](#casting). Similarly, if you expect the result of the operation to be too large for the integer type, perform a [cast](#casting) to a larger size before performing the operation. + +All arithmetic operations abort instead of behaving in a way that mathematical integers would not (e.g., overflow, underflow, divide-by-zero). + +| Syntax | Operation | Aborts If +|--------|-----------|------------------------------------- +| `+` |addition | Result is too large for the integer type +| `-` | subtraction | Result is less than zero +| `*` | multiplication | Result is too large for the integer type +| `%` | modular division | The divisor is `0` +| `/` | truncating division | The divisor is `0` + +### Bitwise + +The integer types support the following bitwise operations that treat each number as a series of individual bits, either 0 or 1, instead of as numerical integer values. + +Bitwise operations do not abort. + +| Syntax | Operation | Description | +|---------------------|-------------|-------------------------------------------------------| +| `&` | bitwise and | Performs a boolean and for each bit pairwise | +| | | bitwise or | Performs a boolean or for each bit pairwise | +| `^` | bitwise xor | Performs a boolean exclusive or for each bit pairwise | + +### Bit Shifts + +Similar to the bitwise operations, each integer type supports bit shifts. But unlike the other operations, the righthand side operand (how many bits to shift by) must *always* be a `u8` and need not match the left side operand (the number you are shifting). + +Bit shifts can abort if the number of bits to shift by is greater than or equal to `8`, `16`, `32`, `64`, `128` or `256` for `u8`, `u16`, `u32`, `u64`, `u128` and `u256` respectively. + +| Syntax | Operation | Aborts if +|--------|------------|---------- +|`<<` | shift left | Number of bits to shift by is greater than the size of the integer type +|`>>` | shift right| Number of bits to shift by is greater than the size of the integer type + +### Comparisons + +Integer types are the *only* types in Move that can use the comparison operators. Both arguments need to be of the same type. If you need to compare integers of different types, you will need to [cast](#casting) one of them first. + +Comparison operations do not abort. + +| Syntax | Operation +|--------|----------- +| `<` | less than +| `>` | greater than +| `<=` | less than or equal to +| `>=` | greater than or equal to + +### Equality + +Like all types with [`drop`](./abilities.md) in Move, all integer types support the ["equal"](./equality.md) and ["not equal"](./equality.md) operations. Both arguments need to be of the same type. If you need to compare integers of different types, you will need to [cast](#casting) one of them first. + +Equality operations do not abort. + +| Syntax | Operation +|--------|---------- +| `==` | equal +| `!=` | not equal + +For more details see the section on [equality](./equality.md) + +## Casting + +Integer types of one size can be cast to integer types of another size. Integers are the only types in Move that support casting. + +Casts *do not* truncate. Casting will abort if the result is too large for the specified type + +| Syntax | Operation | Aborts if +|------------|---------------------------------------------------------------------------------|--------------------------------------- +| `(e as T)`| Cast integer expression `e` into an integer type `T` | `e` is too large to represent as a `T` + +Here, the type of `e` must be `8`, `16`, `32`, `64`, `128` or `256` and `T` must be `u8`, `u16`, `u32`, `u64`, `u128` oe `u256`. + +For example: + +- `(x as u8)` +- `(y as u16)` +- `(873u16 as u32)` +- `(2u8 as u64)` +- `(1 + 3 as u128)` +- `(4/2 + 12345 as u256)` + +## Ownership + +As with the other scalar values built-in to the language, integer values are implicitly copyable, meaning they can be copied without an explicit instruction such as [`copy`](./variables.md#move-and-copy). diff --git a/vendors/move/crates/documentation/book/src/introduction.md b/vendors/move/crates/documentation/book/src/introduction.md new file mode 100644 index 000000000..c2417c517 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/introduction.md @@ -0,0 +1,27 @@ +# Introduction + +Welcome to Move, a next generation language for secure, sandboxed, and formally verified programming. Its first use case is for the Diem blockchain, where Move provides the foundation for its implementation. Move allows developers to write programs that flexibly manage and transfer assets, while providing the security and protections against attacks on those assets. However, Move has been developed with use cases in mind outside a blockchain context as well. + +Move takes its cue from [Rust](https://www.rust-lang.org/) by using resource types with move (hence the name) semantics as an explicit representation of digital assets, such as currency. + +## Who is Move for? + +Move was designed and created as a secure, verified, yet flexible programming language. The first use of Move is for the implementation of the Diem blockchain. That said, the language is still evolving. Move has the potential to be a language for other blockchains, and even non-blockchain use cases as well. + +The early Move Developer is one with some programming experience, who wants to begin understanding the core programming language and see examples of its usage. + +### Hobbyists + +Understanding that the capability to create custom modules on the Diem Payment Network will not be available at launch, the hobbyist Move Developer is interested in learning the intricacies of the language. She will understand the basic syntax, the standard libraries available, and write example code that can be executed using the Move CLI. The Move Developer may even want to dig into understanding how the Move Virtual Machine executes the code she writes. + +### Core Contributor + +Beyond a hobbyist wanting to stay ahead of the curve for the core programming language is someone who may want to [contribute](https://diem.com/en-US/cla-sign/) directly to Move. Whether this includes submitting language improvements or even, in the future, adding core modules available on the Diem Payment Network, the core contributor will understand Move at a deep level. + +### Who Move is currently not targeting + +Currently, Move is not targeting developers who wish to create custom modules and contracts for use on the Diem Payment Network. We are also not targeting novice developers who expect a completely polished developer experience even in testing the language. + +## Where Do I Start? + +Begin with understanding [modules and scripts](./modules-and-scripts.md) and then work through the [Move Tutorial](./creating-coins.md). diff --git a/vendors/move/crates/documentation/book/src/loops.md b/vendors/move/crates/documentation/book/src/loops.md new file mode 100644 index 000000000..2dfac3fdd --- /dev/null +++ b/vendors/move/crates/documentation/book/src/loops.md @@ -0,0 +1,184 @@ +# While and Loop + +Move offers two constructs for looping: `while` and `loop`. + +## `while` loops + +The `while` construct repeats the body (an expression of type unit) until the condition (an expression of type `bool`) evaluates to `false`. + +Here is an example of simple `while` loop that computes the sum of the numbers from `1` to `n`: + +```move +fun sum(n: u64): u64 { + let sum = 0; + let i = 1; + while (i <= n) { + sum = sum + i; + i = i + 1 + }; + + sum +} +``` + +Infinite loops are allowed: + +```move= +fun foo() { + while (true) { } +} +``` + +### `break` + +The `break` expression can be used to exit a loop before the condition evaluates to `false`. For example, this loop uses `break` to find the smallest factor of `n` that's greater than 1: + +```move +fun smallest_factor(n: u64): u64 { + // assuming the input is not 0 or 1 + let i = 2; + while (i <= n) { + if (n % i == 0) break; + i = i + 1 + }; + + i +} +``` + +The `break` expression cannot be used outside of a loop. + +### `continue` + +The `continue` expression skips the rest of the loop and continues to the next iteration. This loop uses `continue` to compute the sum of `1, 2, ..., n`, except when the number is divisible by 10: + +```move +fun sum_intermediate(n: u64): u64 { + let sum = 0; + let i = 0; + while (i < n) { + i = i + 1; + if (i % 10 == 0) continue; + sum = sum + i; + }; + + sum +} +``` + +The `continue` expression cannot be used outside of a loop. + +### The type of `break` and `continue` + +`break` and `continue`, much like `return` and `abort`, can have any type. The following examples illustrate where this flexible typing can be helpful: + +```move +fun pop_smallest_while_not_equal( + v1: vector, + v2: vector, +): vector { + let result = vector::empty(); + while (!vector::is_empty(&v1) && !vector::is_empty(&v2)) { + let u1 = *vector::borrow(&v1, vector::length(&v1) - 1); + let u2 = *vector::borrow(&v2, vector::length(&v2) - 1); + let popped = + if (u1 < u2) vector::pop_back(&mut v1) + else if (u2 < u1) vector::pop_back(&mut v2) + else break; // Here, `break` has type `u64` + vector::push_back(&mut result, popped); + }; + + result +} +``` + +```move +fun pick( + indexes: vector, + v1: &vector
, + v2: &vector
+): vector
{ + let len1 = vector::length(v1); + let len2 = vector::length(v2); + let result = vector::empty(); + while (!vector::is_empty(&indexes)) { + let index = vector::pop_back(&mut indexes); + let chosen_vector = + if (index < len1) v1 + else if (index < len2) v2 + else continue; // Here, `continue` has type `&vector
` + vector::push_back(&mut result, *vector::borrow(chosen_vector, index)) + }; + + result +} +``` + +## The `loop` expression + +The `loop` expression repeats the loop body (an expression with type `()`) until it hits a `break` + +Without a `break`, the loop will continue forever + +```move +fun foo() { + let i = 0; + loop { i = i + 1 } +} +``` + +Here is an example that uses `loop` to write the `sum` function: + +```move +fun sum(n: u64): u64 { + let sum = 0; + let i = 0; + loop { + i = i + 1; + if (i > n) break; + sum = sum + i + }; + + sum +} +``` + +As you might expect, `continue` can also be used inside a `loop`. Here is `sum_intermediate` from above rewritten using `loop` instead of `while` + +```move +fun sum_intermediate(n: u64): u64 { + let sum = 0; + let i = 0; + loop { + i = i + 1; + if (i % 10 == 0) continue; + if (i > n) break; + sum = sum + i + }; + + sum +} +``` + +## The type of `while` and `loop` + +Move loops are typed expressions. A `while` expression always has type `()`. + +```move +let () = while (i < 10) { i = i + 1 }; +``` + +If a `loop` contains a `break`, the expression has type unit `()` + +```move +(loop { if (i < 10) i = i + 1 else break }: ()); +let () = loop { if (i < 10) i = i + 1 else break }; +``` + +If `loop` does not have a `break`, `loop` can have any type much like `return`, `abort`, `break`, and `continue`. + +```move +(loop (): u64); +(loop (): address); +(loop (): &vector>); +``` diff --git a/vendors/move/crates/documentation/book/src/modules-and-scripts.md b/vendors/move/crates/documentation/book/src/modules-and-scripts.md new file mode 100644 index 000000000..f3580e4de --- /dev/null +++ b/vendors/move/crates/documentation/book/src/modules-and-scripts.md @@ -0,0 +1,131 @@ +# Modules and Scripts + +Move has two different types of programs: ***Modules*** and ***Scripts***. Modules are libraries that define struct types along with functions that operate on these types. Struct types define the schema of Move's [global storage](./global-storage-structure.md), and module functions define the rules for updating storage. Modules themselves are also stored in global storage. Scripts are executable entrypoints similar to a `main` function in a conventional language. A script typically calls functions of a published module that perform updates to global storage. Scripts are ephemeral code snippets that are not published in global storage. + +A Move source file (or **compilation unit**) may contain multiple modules and scripts. However, publishing a module or executing a script are separate VM operations. + +## Syntax + +### Scripts + +A script has the following structure: + +```text +script { + * + * + fun <[type parameters: constraint]*>([identifier: type]*) +} +``` + +A `script` block must start with all of its [`use`](./uses.md) declarations, followed by any [constants](./constants.md) and (finally) the main +[function](./functions.md) declaration. +The main function can have any name (i.e., it need not be called `main`), is the only function in a script block, can have any number of +arguments, and must not return a value. Here is an example with each of these components: + +```move +script { + // Import the debug module published at the named account address std. + use std::debug; + + const ONE: u64 = 1; + + fun main(x: u64) { + let sum = x + ONE; + debug::print(&sum) + } +} +``` + +Scripts have very limited power—they cannot declare friends, struct types or access global storage. Their primary purpose is to invoke module functions. + +### Modules + +A module has the following syntax: + +```text +module
:: { + ( | | | | )* +} +``` + +where `
` is a valid [named or literal address](./address.md). + +For example: + +```move +module 0x42::test { + struct Example has copy, drop { i: u64 } + + use std::debug; + friend 0x42::another_test; + + const ONE: u64 = 1; + + public fun print(x: u64) { + let sum = x + ONE; + let example = Example { i: sum }; + debug::print(&sum) + } +} +``` + +The `module 0x42::test` part specifies that the module `test` will be published under the [account address](./address.md) `0x42` in [global storage](./global-storage-structure.md). + +Modules can also be declared using [named addresses](./address.md). For example: + +```move +module test_addr::test { + struct Example has copy, drop { a: address } + + use std::debug; + friend test_addr::another_test; + + public fun print() { + let example = Example { a: @test_addr }; + debug::print(&example) + } +} +``` + +Because named addresses only exist at the source language level and during compilation, +named addresses will be fully substituted for their value at the bytecode +level. For example if we had the following code: + +```move +script { + fun example() { + my_addr::m::foo(@my_addr); + } +} +``` + +and we compiled it with `my_addr` set to `0xC0FFEE`, then it would be equivalent +to the following operationally: + +```move +script { + fun example() { + 0xC0FFEE::m::foo(@0xC0FFEE); + } +} +``` + +However at the source level, these _are not equivalent_—the function +`m::foo` _must_ be accessed through the `my_addr` named address, and not through +the numerical value assigned to that address. + +Module names can start with letters `a` to `z` or letters `A` to `Z`. After the first character, module names can contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, or digits `0` to `9`. + +```move +module my_module {} +module foo_bar_42 {} +``` + +Typically, module names start with an lowercase letter. A module named `my_module` should be stored in a source file named `my_module.move`. + +All elements inside a `module` block can appear in any order. +Fundamentally, a module is a collection of [`types`](./structs-and-resources.md) and [`functions`](./functions.md). +The [`use`](./uses.md) keyword is used to import types from other modules. +The [`friend`](./friends.md) keyword specifies a list of trusted modules. +The [`const`](./constants.md) keyword defines private constants that can be used in the functions of a module. diff --git a/vendors/move/crates/documentation/book/src/overview.md b/vendors/move/crates/documentation/book/src/overview.md new file mode 100644 index 000000000..d08bf4352 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/overview.md @@ -0,0 +1,200 @@ +--- +id: overview +title: Overview +sidebar_label: Move +--- + +Move is a next generation language for secure, sandboxed, and formally verified programming. Its first use case is for the Diem blockchain, where Move provides the foundation for its implementation. However, Move has been developed with use cases in mind outside a blockchain context as well. + +### Start Here + + + + + + + +### Primitive Types + + + + + + + + + + + +### Basic Concepts + + + + + + + + + + + + + + +### Global Storage + + + + + + +### Reference + + + + + diff --git a/vendors/move/crates/documentation/book/src/packages.md b/vendors/move/crates/documentation/book/src/packages.md new file mode 100644 index 000000000..c4abace5c --- /dev/null +++ b/vendors/move/crates/documentation/book/src/packages.md @@ -0,0 +1,292 @@ +# Packages + +Packages allow Move programmers to more easily re-use code and share it +across projects. The Move package system allows programmers to easily: +* Define a package containing Move code; +* Parameterize a package by [named addresses](./address.md); +* Import and use packages in other Move code and instantiate named addresses; +* Build packages and generate associated compilation artifacts from packages; and +* Work with a common interface around compiled Move artifacts. + +## Package Layout and Manifest Syntax + +A Move package source directory contains a `Move.toml` package manifest +file along with a set of subdirectories: + +``` +a_move_package +├── Move.toml (required) +├── sources (required) +├── examples (optional, test & dev mode) +├── scripts (optional) +├── doc_templates (optional) +└── tests (optional, test mode) +``` + +The directories marked `required` _must_ be present in order for the directory +to be considered a Move package and to be compiled. Optional directories can +be present, and if so will be included in the compilation process. Depending on +the mode that the package is built with (`test` or `dev`), the `tests` and +`examples` directories will be included as well. + +The `sources` directory can contain both Move modules and Move scripts (both +transaction scripts and modules containing script functions). The `examples` +directory can hold additional code to be used only for development and/or +tutorial purposes that will not be included when compiled outside `test` or +`dev` mode. + +A `scripts` directory is supported so transaction scripts can be separated +from modules if that is desired by the package author. The `scripts` +directory will always be included for compilation if it is present. +Documentation will be built using any documentation templates present in +the `doc_templates` directory. + +### Move.toml + +The Move package manifest is defined within the `Move.toml` file and has the +following syntax. Optional fields are marked with `*`, `+` denotes +one or more elements: + +``` +[package] +name = # e.g., "MoveStdlib" +version = ".." # e.g., "0.1.1" +license* = # e.g., "MIT", "GPL", "Apache 2.0" +authors* = [] # e.g., ["Joe Smith (joesmith@noemail.com)", "Jane Smith (janesmith@noemail.com)"] + +[addresses] # (Optional section) Declares named addresses in this package and instantiates named addresses in the package graph +# One or more lines declaring named addresses in the following format + = "_" | "" # e.g., std = "_" or my_addr = "0xC0FFEECAFE" + +[dependencies] # (Optional section) Paths to dependencies and instantiations or renamings of named addresses from each dependency +# One or more lines declaring dependencies in the following format + = { local = , addr_subst* = { ( = ( | ""))+ } } # local dependencies + = { git = , subdir=, rev=, addr_subst* = { ( = ( | ""))+ } } # git dependencies + +[dev-addresses] # (Optional section) Same as [addresses] section, but only included in "dev" and "test" modes +# One or more lines declaring dev named addresses in the following format + = "_" | "" # e.g., std = "_" or my_addr = "0xC0FFEECAFE" + +[dev-dependencies] # (Optional section) Same as [dependencies] section, but only included in "dev" and "test" modes +# One or more lines declaring dev dependencies in the following format + = { local = , addr_subst* = { ( = ( |
))+ } } +``` + +An example of a minimal package manifest with one local dependency and one git dependency: + +``` +[package] +name = "AName" +version = "0.0.0" +``` + +An example of a more standard package manifest that also includes the Move +standard library and instantiates the named address `Std` from it with the +address value `0x1`: + +``` +[package] +name = "AName" +version = "0.0.0" +license = "Apache 2.0" + +[addresses] +address_to_be_filled_in = "_" +specified_address = "0xB0B" + +[dependencies] +# Local dependency +LocalDep = { local = "projects/move-awesomeness", addr_subst = { "std" = "0x1" } } +# Git dependency +MoveStdlib = { git = "https://github.com/diem/diem.git", subdir="language/move-stdlib", rev = "56ab033cc403b489e891424a629e76f643d4fb6b" } + +[dev-addresses] # For use when developing this module +address_to_be_filled_in = "0x101010101" +``` + +Most of the sections in the package manifest are self explanatory, but named +addresses can be a bit difficult to understand so it's worth examining them in +a bit more detail. + +## Named Addresses During Compilation + +Recall that Move has [named addresses](./address.md) and that +named addresses cannot be declared in Move. Because of this, until now +named addresses and their values needed to be passed to the compiler on the +command line. With the Move package system this is no longer needed, and +you can declare named addresses in the package, instantiate other named +addresses in scope, and rename named addresses from other packages within +the Move package system manifest file. Let's go through each of these +individually: + +### Declaration + +Let's say we have a Move module in `example_pkg/sources/A.move` as follows: + +```move +module named_addr::A { + public fun x(): address { @named_addr } +} +``` + +We could in `example_pkg/Move.toml` declare the named address `named_addr` in +two different ways. The first: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +named_addr = "_" +``` + +Declares `named_addr` as a named address in the package `ExamplePkg` and +that _this address can be any valid address value_. Therefore an importing +package can pick the value of the named address `named_addr` to be any address +it wishes. Intuitively you can think of this as parameterizing the package +`ExamplePkg` by the named address `named_addr`, and the package can then be +instantiated later on by an importing package. + +`named_addr` can also be declared as: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +named_addr = "0xCAFE" +``` + +which states that the named address `named_addr` is exactly `0xCAFE` and cannot be +changed. This is useful so other importing packages can use this named +address without needing to worry about the exact value assigned to it. + +With these two different declaration methods, there are two ways that +information about named addresses can flow in the package graph: +* The former ("unassigned named addresses") allows named address values to flow + from the importation site to the declaration site. +* The latter ("assigned named addresses") allows named address values to flow + from the declaration site upwards in the package graph to usage sites. + +With these two methods for flowing named address information throughout the +package graph the rules around scoping and renaming become important to +understand. + +## Scoping and Renaming of Named Addresses + +A named address `N` in a package `P` is in scope if: +1. It declares a named address `N`; or +2. A package in one of `P`'s transitive dependencies declares the named address + `N` and there is a dependency path in the package graph between between `P` and the + declaring package of `N` with no renaming of `N`. + +Additionally, every named address in a package is exported. Because of this and +the above scoping rules each package can be viewed as coming with a set of +named addresses that will be brought into scope when the package is imported, +e.g., if the `ExamplePkg` package was imported, that importation would bring +into scope the `named_addr` named address. Because of this, if `P` imports two +packages `P1` and `P2` both of which declare a named address `N` an issue +arises in `P`: which "`N`" is meant when `N` is referred to in `P`? The one +from `P1` or `P2`? To prevent this ambiguity around which package a named +address is coming from, we enforce that the sets of scopes introduced by all +dependencies in a package are disjoint, and provide a way to _rename named +addresses_ when the package that brings them into scope is imported. + +Renaming a named address when importing can be done as follows in our `P`, +`P1`, and `P2` example above: + +``` +[package] +name = "P" +... +[dependencies] +P1 = { local = "some_path_to_P1", addr_subst = { "P1N" = "N" } } +P2 = { local = "some_path_to_P2" } +``` + +With this renaming `N` refers to the `N` from `P2` and `P1N` will refer to `N` +coming from `P1`: + +``` +module N::A { + public fun x(): address { @P1N } +} +``` + +It is important to note that _renaming is not local_: once a named address `N` +has been renamed to `N2` in a package `P` all packages that import `P` will not +see `N` but only `N2` unless `N` is reintroduced from outside of `P`. This is +why rule (2) in the scoping rules at the start of this section specifies a +"dependency path in the package graph between between `P` and the declaring +package of `N` with no renaming of `N`." + +### Instantiation + +Named addresses can be instantiated multiple times across the package graph as +long as it is always with the same value. It is an error if the same named +address (regardless of renaming) is instantiated with differing values across +the package graph. + +A Move package can only be compiled if all named addresses resolve to a value. +This presents issues if the package wishes to expose an uninstantiated named +address. This is what the `[dev-addresses]` section solves. This section can +set values for named addresses, but cannot introduce any named addresses. +Additionally, only the `[dev-addresses]` in the root package are included in +`dev` mode. For example a root package with the following manifest would not compile +outside of `dev` mode since `named_addr` would be uninstantiated: + +``` +[package] +name = "ExamplePkg" +... +[addresses] +named_addr = "_" + +[dev-addresses] +named_addr = "0xC0FFEE" +``` + +## Usage, Artifacts, and Data Structures + +The Move package system comes with a command line option as part of the Move +CLI `move `. Unless a +particular path is provided, all package commands will run in the current working +directory. The full list of commands and flags for the Move CLI can be found by +running `move --help`. + +### Usage + +A package can be compiled either through the Move CLI commands, or as a library +command in Rust with the function `compile_package`. This will create a +`CompiledPackage` that holds the compiled bytecode along with other compilation +artifacts (source maps, documentation, ABIs) in memory. This `CompiledPackage` +can be converted to an `OnDiskPackage` and vice versa -- the latter being the data of +the `CompiledPackage` laid out in the file system in the following format: + +``` +a_move_package +├── Move.toml +... +└── build + ├── + │   ├── BuildInfo.yaml + │   ├── bytecode_modules + │   │   └── *.mv + │   ├── source_maps + │   │   └── *.mvsm + │ ├── bytecode_scripts + │ │   └── *.mv + │ ├── abis + │ │   ├── *.abi + │ │   └── /*.abi + │   └── sources + │   └── *.move + ... + └── + ├── BuildInfo.yaml + ... + └── sources +``` + +See the `move-package` crate for more information on these data structures and +how to use the Move package system as a Rust library. diff --git a/vendors/move/crates/documentation/book/src/references.md b/vendors/move/crates/documentation/book/src/references.md new file mode 100644 index 000000000..57a5b99e1 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/references.md @@ -0,0 +1,235 @@ +# References + +Move has two types of references: immutable `&` and mutable `&mut`. Immutable references are read +only, and cannot modify the underlying value (or any of its fields). Mutable references allow for +modifications via a write through that reference. Move's type system enforces an ownership +discipline that prevents reference errors. + +For more details on the rules of references, see [Structs and Resources](./structs-and-resources.md) + +## Reference Operators + +Move provides operators for creating and extending references as well as converting a mutable +reference to an immutable one. Here and elsewhere, we use the notation `e: T` for "expression `e` +has type `T`". + +| Syntax | Type | Description | +| ----------- | ----------------------------------------------------- | -------------------------------------------------------------- | +| `&e` | `&T` where `e: T` and `T` is a non-reference type | Create an immutable reference to `e` | +| `&mut e` | `&mut T` where `e: T` and `T` is a non-reference type | Create a mutable reference to `e`. | +| `&e.f` | `&T` where `e.f: T` | Create an immutable reference to field `f` of struct `e`. | +| `&mut e.f` | `&mut T` where `e.f: T` | Create a mutable reference to field `f` of struct`e`. | +| `freeze(e)` | `&T` where `e: &mut T` | Convert the mutable reference `e` into an immutable reference. | + +The `&e.f` and `&mut e.f` operators can be used both to create a new reference into a struct or to +extend an existing reference: + +```move +let s = S { f: 10 }; +let f_ref1: &u64 = &s.f; // works +let s_ref: &S = &s; +let f_ref2: &u64 = &s_ref.f // also works +``` + +A reference expression with multiple fields works as long as both structs are in the same module: + +```move +struct A { b: B } +struct B { c : u64 } +fun f(a: &A): &u64 { + &a.b.c +} +``` + +Finally, note that references to references are not allowed: + +```move +let x = 7; +let y: &u64 = &x; +let z: &&u64 = &y; // will not compile +``` + +## Reading and Writing Through References + +Both mutable and immutable references can be read to produce a copy of the referenced value. + +Only mutable references can be written. A write `*x = v` discards the value previously stored in `x` +and updates it with `v`. + +Both operations use the C-like `*` syntax. However, note that a read is an expression, whereas a +write is a mutation that must occur on the left hand side of an equals. + +| Syntax | Type | Description | +| ---------- | ----------------------------------- | ----------------------------------- | +| `*e` | `T` where `e` is `&T` or `&mut T` | Read the value pointed to by `e` | +| `*e1 = e2` | `()` where `e1: &mut T` and `e2: T` | Update the value in `e1` with `e2`. | + +In order for a reference to be read, the underlying type must have the +[`copy` ability](./abilities.md) as reading the reference creates a new copy of the value. This rule +prevents the copying of resource values: + +```move= +fun copy_resource_via_ref_bad(c: Coin) { + let c_ref = &c; + let counterfeit: Coin = *c_ref; // not allowed! + pay(c); + pay(counterfeit); +} +``` + +Dually: in order for a reference to be written to, the underlying type must have the +[`drop` ability](./abilities.md) as writing to the reference will discard (or "drop") the old value. +This rule prevents the destruction of resource values: + +```move= +fun destroy_resource_via_ref_bad(ten_coins: Coin, c: Coin) { + let ref = &mut ten_coins; + *ref = c; // not allowed--would destroy 10 coins! +} +``` + +## `freeze` inference + +A mutable reference can be used in a context where an immutable reference is expected: + +```move +let x = 7; +let y: &u64 = &mut x; +``` + +This works because the under the hood, the compiler inserts `freeze` instructions where they are +needed. Here are a few more examples of `freeze` inference in action: + +```move= +fun takes_immut_returns_immut(x: &u64): &u64 { x } + +// freeze inference on return value +fun takes_mut_returns_immut(x: &mut u64): &u64 { x } + +fun expression_examples() { + let x = 0; + let y = 0; + takes_immut_returns_immut(&x); // no inference + takes_immut_returns_immut(&mut x); // inferred freeze(&mut x) + takes_mut_returns_immut(&mut x); // no inference + + assert!(&x == &mut y, 42); // inferred freeze(&mut y) +} + +fun assignment_examples() { + let x = 0; + let y = 0; + let imm_ref: &u64 = &x; + + imm_ref = &x; // no inference + imm_ref = &mut y; // inferred freeze(&mut y) +} +``` + +### Subtyping + +With this `freeze` inference, the Move type checker can view `&mut T` as a subtype of `&T`. As shown +above, this means that anywhere for any expression where a `&T` value is used, a `&mut T` value can +also be used. This terminology is used in error messages to concisely indicate that a `&mut T` was +needed where a `&T` was supplied. For example + +```move= +address 0x42 { +module example { + fun read_and_assign(store: &mut u64, new_value: &u64) { + *store = *new_value + } + + fun subtype_examples() { + let x: &u64 = &0; + let y: &mut u64 = &mut 1; + + x = &mut 1; // valid + y = &2; // invalid! + + read_and_assign(y, x); // valid + read_and_assign(x, y); // invalid! + } +} +} +``` + +will yield the following error messages + +```text +error: + + ┌── example.move:12:9 ─── + │ + 12 │ y = &2; // invalid! + │ ^ Invalid assignment to local 'y' + · + 12 │ y = &2; // invalid! + │ -- The type: '&{integer}' + · + 9 │ let y: &mut u64 = &mut 1; + │ -------- Is not a subtype of: '&mut u64' + │ + +error: + + ┌── example.move:15:9 ─── + │ + 15 │ read_and_assign(x, y); // invalid! + │ ^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x42::example::read_and_assign'. Invalid argument for parameter 'store' + · + 8 │ let x: &u64 = &0; + │ ---- The type: '&u64' + · + 3 │ fun read_and_assign(store: &mut u64, new_value: &u64) { + │ -------- Is not a subtype of: '&mut u64' + │ +``` + +The only other types currently that has subtyping are [tuples](./tuples.md) + +## Ownership + +Both mutable and immutable references can always be copied and extended _even if there are existing +copies or extensions of the same reference_: + +```move +fun reference_copies(s: &mut S) { + let s_copy1 = s; // ok + let s_extension = &mut s.f; // also ok + let s_copy2 = s; // still ok + ... +} +``` + +This might be surprising for programmers familiar with Rust's ownership system, which would reject +the code above. Move's type system is more permissive in its treatment of +[copies](./variables.md#move-and-copy), but equally strict in ensuring unique ownership of mutable +references before writes. + +### References Cannot Be Stored + +References and tuples are the _only_ types that cannot be stored as a field value of structs, which +also means that they cannot exist in global storage. All references created during program execution +will be destroyed when a Move program terminates; they are entirely ephemeral. This invariant is +also true for values of types without the `store` [ability](./abilities.md), but note that +references and tuples go a step further by never being allowed in structs in the first place. + +This is another difference between Move and Rust, which allows references to be stored inside of +structs. + +Currently, Move cannot support this because references cannot be +[serialized](https://en.wikipedia.org/wiki/Serialization), but _every Move value must be +serializable_. This requirement comes from Move's +[persistent global storage](./global-storage-structure.md), which needs to serialize values to +persist them across program executions. Structs can be written to global storage, and thus they must +be serializable. + +One could imagine a fancier, more expressive, type system that would allow references to be stored +in structs _and_ ban those structs from existing in global storage. We could perhaps allow +references inside of structs that do not have the `store` [ability](./abilities.md), but that would +not completely solve the problem: Move has a fairly complex system for tracking static reference +safety, and this aspect of the type system would also have to be extended to support storing +references inside of structs. In short, Move's type system (particularly the aspects around +reference safety) would have to expand to support stored references. But it is something we are +keeping an eye on as the language evolves. diff --git a/vendors/move/crates/documentation/book/src/signer.md b/vendors/move/crates/documentation/book/src/signer.md new file mode 100644 index 000000000..820963c8b --- /dev/null +++ b/vendors/move/crates/documentation/book/src/signer.md @@ -0,0 +1,73 @@ +# Signer + +`signer` is a built-in Move resource type. A `signer` is a +[capability](https://en.wikipedia.org/wiki/Object-capability_model) that allows the holder to act on +behalf of a particular `address`. You can think of the native implementation as being: + +```move +struct signer has drop { a: address } +``` + +A `signer` is somewhat similar to a Unix [UID](https://en.wikipedia.org/wiki/User_identifier) in +that it represents a user authenticated by code _outside_ of Move (e.g., by checking a cryptographic +signature or password). + +## Comparison to `address` + +A Move program can create any `address` value without special permission using address literals: + +```move +let a1 = @0x1; +let a2 = @0x2; +// ... and so on for every other possible address +``` + +However, `signer` values are special because they cannot be created via literals or +instructions--only by the Move VM. Before the VM runs a script with parameters of type `signer`, it +will automatically create `signer` values and pass them into the script: + +```move +script { + use std::signer; + fun main(s: signer) { + assert!(signer::address_of(&s) == @0x42, 0); + } +} +``` + +This script will abort with code `0` if the script is sent from any address other than `0x42`. + +A transaction script can have an arbitrary number of `signer`s as long as the `signer`s are a prefix +to any other arguments. In other words, all of the `signer` arguments must come first: + +```move +script { + use std::signer; + fun main(s1: signer, s2: signer, x: u64, y: u8) { + // ... + } +} +``` + +This is useful for implementing _multi-signer scripts_ that atomically act with the authority of +multiple parties. For example, an extension of the script above could perform an atomic currency +swap between `s1` and `s2`. + +## `signer` Operators + +The `std::signer` standard library module provides two utility functions over `signer` values: + +| Function | Description | +| ------------------------------------------- | ------------------------------------------------------------- | +| `signer::address_of(&signer): address` | Return the `address` wrapped by this `&signer`. | +| `signer::borrow_address(&signer): &address` | Return a reference to the `address` wrapped by this `&signer`. | + +In addition, the `move_to(&signer, T)` [global storage operator](./global-storage-operators.md) +requires a `&signer` argument to publish a resource `T` under `signer.address`'s account. This +ensures that only an authenticated user can elect to publish a resource under their `address`. + +## Ownership + +Unlike simple scalar values, `signer` values are not copyable, meaning they cannot be copied (from +any operation whether it be through an explicit [`copy`](./variables.md#move-and-copy) instruction +or through a [dereference `*`](./references.md#reading-and-writing-through-references). diff --git a/vendors/move/crates/documentation/book/src/standard-library.md b/vendors/move/crates/documentation/book/src/standard-library.md new file mode 100644 index 000000000..045c99aa4 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/standard-library.md @@ -0,0 +1,542 @@ +# Standard Library + +The Move standard library exposes interfaces that implement the following functionality: +* [Basic operations on vectors](#vector). +* [Option types and operations on`Option` types](#option). +* [A common error encoding code interface for abort codes](#errors). +* [32-bit precision fixed-point numbers](#fixed_point32). + +## vector + +The `vector` module defines a number of operations over the primitive +[`vector`](./vector.md) type. The module is published under the +named address `Std` and consists of a number of native functions, as +well as functions defined in Move. The API for this module is as follows. + +### Functions + +--------------------------------------------------------------------------- + +Create an empty [`vector`](./vector.md). +The `Element` type can be both a `resource` or `copyable` type. + +```move + native public fun empty(): vector; +``` + +--------------------------------------------------------------------------- + +Create a vector of length `1` containing the passed in `element`. + +```move + public fun singleton(e: Element): vector; +``` + +--------------------------------------------------------------------------- + +Destroy (deallocate) the vector `v`. Will abort if `v` is non-empty. +*Note*: The emptiness restriction is due to the fact that `Element` can be a +resource type, and destruction of a non-empty vector would violate +[resource conservation](./structs-and-resources.md). + +```move + native public fun destroy_empty(v: vector); +``` + +--------------------------------------------------------------------------- + +Acquire an [immutable reference](./references.md) to the `i`th element of the vector `v`. Will abort if +the index `i` is out of bounds for the vector `v`. + +```move + native public fun borrow(v: &vector, i: u64): ∈ +``` + +--------------------------------------------------------------------------- + +Acquire a [mutable reference](./references.md) +to the `i`th element of the vector `v`. Will abort if +the index `i` is out of bounds for the vector `v`. + +```move + native public fun borrow_mut(v: &mut vector, i: u64): &mut Element; +``` + +--------------------------------------------------------------------------- + +Empty and destroy the `other` vector, and push each of the elements in +the `other` vector onto the `lhs` vector in the same order as they occurred in `other`. + +```move + public fun append(lhs: &mut vector, other: vector); +``` + +--------------------------------------------------------------------------- + +Push an element `e` of type `Element` onto the end of the vector `v`. May +trigger a resizing of the underlying vector's memory. + +```move + native public fun push_back(v: &mut vector, e: Element); +``` + +--------------------------------------------------------------------------- + +Pop an element from the end of the vector `v` in-place and return the owned +value. Will abort if `v` is empty. + +```move + native public fun pop_back(v: &mut vector): Element; +``` + +--------------------------------------------------------------------------- + +Remove the element at index `i` in the vector `v` and return the owned value +that was previously stored at `i` in `v`. All elements occurring at indices +greater than `i` will be shifted down by 1. Will abort if `i` is out of bounds +for `v`. + +```move + public fun remove(v: &mut vector, i: u64): Element; +``` + +--------------------------------------------------------------------------- + +Swap the `i`th element of the vector `v` with the last element and then pop +this element off of the back of the vector and return the owned value that +was previously stored at index `i`. +This operation is O(1), but does not preserve ordering of elements in the vector. +Aborts if the index `i` is out of bounds for the vector `v`. + +```move + public fun swap_remove(v: &mut vector, i: u64): Element; +``` + +--------------------------------------------------------------------------- + +Swap the elements at the `i`'th and `j`'th indices in the vector `v`. Will +abort if either of `i` or `j` are out of bounds for `v`. + +```move + native public fun swap(v: &mut vector, i: u64, j: u64); +``` + +--------------------------------------------------------------------------- + +Reverse the order of the elements in the vector `v` in-place. + +```move + public fun reverse(v: &mut vector); +``` + +--------------------------------------------------------------------------- + +Return the index of the first occurrence of an element in `v` that is +equal to `e`. Returns `(true, index)` if such an element was found, and +`(false, 0)` otherwise. + +```move + public fun index_of(v: &vector, e: &Element): (bool, u64); +``` + +--------------------------------------------------------------------------- + +Return if an element equal to `e` exists in the vector `v`. + +```move + public fun contains(v: &vector, e: &Element): bool; +``` + +--------------------------------------------------------------------------- + +Return the length of a `vector`. + +```move + native public fun length(v: &vector): u64; +``` + +--------------------------------------------------------------------------- + +Return whether the vector `v` is empty. + +```move + public fun is_empty(v: &vector): bool; +``` + +--------------------------------------------------------------------------- + +## option + +The `option` module defines a generic option type `Option` that represents a +value of type `T` that may, or may not, be present. It is published under the named address `Std`. + +The Move option type is internally represented as a singleton vector, and may +contain a value of `resource` or `copyable` kind. If you are familiar with option +types in other languages, the Move `Option` behaves similarly to those with a +couple notable exceptions since the option can contain a value of kind `resource`. +Particularly, certain operations such as `get_with_default` and +`destroy_with_default` require that the element type `T` be of `copyable` kind. + +The API for the `option` module is as as follows + +### Types + +Generic type abstraction of a value that may, or may not, be present. Can contain +a value of either `resource` or `copyable` kind. + +```move + struct Option; +``` + +### Functions + +Create an empty `Option` of that can contain a value of `Element` type. + +```move + public fun none(): Option; +``` + +--------------------------------------------------------------------------- + +Create a non-empty `Option` type containing a value `e` of type `Element`. + +```move + public fun some(e: T): Option; +``` + +--------------------------------------------------------------------------- + +Return an immutable reference to the value inside the option `opt_elem` +Will abort if `opt_elem` does not contain a value. + +```move + public fun borrow(opt_elem: &Option): ∈ +``` + +--------------------------------------------------------------------------- + +Return a reference to the value inside `opt_elem` if it contains one. If +`opt_elem` does not contain a value the passed in `default_ref` reference will be returned. +Does not abort. + +```move + public fun borrow_with_default(opt_elem: &Option, default_ref: &Element): ∈ +``` + +--------------------------------------------------------------------------- + +Return a mutable reference to the value inside `opt_elem`. Will abort if +`opt_elem` does not contain a value. + +```move + public fun borrow_mut(opt_elem: &mut Option): &mut Element; +``` + +--------------------------------------------------------------------------- + +Convert an option value that contains a value to one that is empty in-place by +removing and returning the value stored inside `opt_elem`. +Will abort if `opt_elem` does not contain a value. + +```move + public fun extract(opt_elem: &mut Option): Element; +``` + +--------------------------------------------------------------------------- + +Return the value contained inside the option `opt_elem` if it contains one. +Will return the passed in `default` value if `opt_elem` does not contain a +value. The `Element` type that the `Option` type is instantiated with must be +of `copyable` kind in order for this function to be callable. + +```move + public fun get_with_default(opt_elem: &Option, default: Element): Element; +``` + +--------------------------------------------------------------------------- + +Convert an empty option `opt_elem` to an option value that contains the value `e`. +Will abort if `opt_elem` already contains a value. + +```move + public fun fill(opt_elem: &mut Option, e: Element); +``` + +--------------------------------------------------------------------------- + +Swap the value currently contained in `opt_elem` with `new_elem` and return the +previously contained value. Will abort if `opt_elem` does not contain a value. + +```move + public fun swap(opt_elem: &mut Option, e: Element): Element; +``` + +--------------------------------------------------------------------------- + +Return true if `opt_elem` contains a value equal to the value of `e_ref`. +Otherwise, `false` will be returned. + +```move + public fun contains(opt_elem: &Option, e_ref: &Element): bool; +``` + +--------------------------------------------------------------------------- + +Return `true` if `opt_elem` does not contain a value. + +```move + public fun is_none(opt_elem: &Option): bool; +``` + +--------------------------------------------------------------------------- + +Return `true` if `opt_elem` contains a value. + +```move + public fun is_some(opt_elem: &Option): bool; +``` + +--------------------------------------------------------------------------- + +Unpack `opt_elem` and return the value that it contained. +Will abort if `opt_elem` does not contain a value. + +```move + public fun destroy_some(opt_elem: Option): Element; +``` + +--------------------------------------------------------------------------- + +Destroys the `opt_elem` value passed in. If `opt_elem` contained a value it +will be returned otherwise, the passed in `default` value will be returned. + +```move + public fun destroy_with_default(opt_elem: Option, default: Element): Element; +``` + +--------------------------------------------------------------------------- + +Destroys the `opt_elem` value passed in, `opt_elem` must be empty and not +contain a value. Will abort if `opt_elem` contains a value. + +```move + public fun destroy_none(opt_elem: Option); +``` + +## errors + +Recall that each abort code in Move is represented as an unsigned 64-bit integer. The `errors` module defines a common interface that can be used to "tag" each of these abort codes so that they can represent both the error **category** along with an error **reason**. + +Error categories are declared as constants in the `errors` module and are globally unique with respect to this module. Error reasons on the other hand are module-specific error codes, and can provide greater detail (perhaps, even a particular _reason_) about the specific error condition. This representation of a category and reason for each error code is done by dividing the abort code into two sections. + +The lower 8 bits of the abort code hold the *error category*. The remaining 56 bits of the abort code hold the *error reason*. +The reason should be a unique number relative to the module which raised the error and can be used to obtain more information about the error at hand. It should mostly be used for diagnostic purposes as error reasons may change over time if the module is updated. + +| Category | Reason | +|----------|--------| +| 8 bits | 56 bits| + +Since error categories are globally stable, these present the most stable API and should in general be what is used by clients to determine the messages they may present to users (whereas the reason is useful for diagnostic purposes). There are public functions in the `errors` module for creating an abort code of each error category with a specific `reason` number (represented as a `u64`). + +### Constants + +The system is in a state where the performed operation is not allowed. + +```move + const INVALID_STATE: u8 = 1; +``` + +--------------------------------------------------------------------------- +A specific account address was required to perform an operation, but a different address from what was expected was encountered. + +```move + const REQUIRES_ADDRESS: u8 = 2; +``` + +--------------------------------------------------------------------------- +An account did not have the expected role for this operation. Useful for Role Based Access Control (RBAC) error conditions. + +```move + const REQUIRES_ROLE: u8 = 3; +``` + +--------------------------------------------------------------------------- +An account did not not have a required capability. Useful for RBAC error conditions. + +```move + const REQUIRES_CAPABILITY: u8 = 4; +``` + +--------------------------------------------------------------------------- +A resource was expected, but did not exist under an address. + +```move + const NOT_PUBLISHED: u8 = 5; +``` + +--------------------------------------------------------------------------- +Attempted to publish a resource under an address where one was already published. + +```move + const ALREADY_PUBLISHED: u8 = 6; +``` + +--------------------------------------------------------------------------- +An argument provided for an operation was invalid. + +```move + const INVALID_ARGUMENT: u8 = 7; +``` + +--------------------------------------------------------------------------- +A limit on a value was exceeded. + +```move + const LIMIT_EXCEEDED: u8 = 8; +``` + +--------------------------------------------------------------------------- +An internal error (bug) has occurred. + +```move + const INTERNAL: u8 = 10; +``` + +--------------------------------------------------------------------------- +A custom error category for extension points. + +```move + const CUSTOM: u8 = 255; +``` + +--------------------------------------------------------------------------- + +### Functions + + Should be used in the case where invalid (global) state is encountered. Constructs an abort code with specified `reason` and category `INVALID_STATE`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun invalid_state(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an account's address does not match a specific address. Constructs an abort code with specified `reason` and category `REQUIRES_ADDRESS`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun requires_address(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a role did not match a required role when using RBAC. Constructs an abort code with specified `reason` and category `REQUIRES_ROLE`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun requires_role(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an account did not have a required capability when using RBAC. Constructs an abort code with specified `reason` and category `REQUIRES_CAPABILITY`. Should be Will abort if `reason` does not fit in 56 bits. + +```move + public fun requires_capability(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a resource did not exist where one was expected. Constructs an abort code with specified `reason` and category `NOT_PUBLISHED`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun not_published(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a resource already existed where one was about to be published. Constructs an abort code with specified `reason` and category `ALREADY_PUBLISHED`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun already_published(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an invalid argument was passed to a function/operation. Constructs an abort code with specified `reason` and category `INVALID_ARGUMENT`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun invalid_argument(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a limit on a specific value is reached, e.g., subtracting 1 from a value of 0. Constructs an abort code with specified `reason` and category `LIMIT_EXCEEDED`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun limit_exceeded(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an internal error or bug was encountered. Constructs an abort code with specified `reason` and category `INTERNAL`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun internal(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Used for extension points, should be not used under most circumstances. Constructs an abort code with specified `reason` and category `CUSTOM`. Will abort if `reason` does not fit in 56 bits. + +```move + public fun custom(reason: u64): u64; +``` + +--------------------------------------------------------------------------- + +## fixed_point32 + +The `fixed_point32` module defines a fixed-point numeric type with 32 integer bits and 32 fractional bits. Internally, this is represented as a `u64` integer wrapped in a struct to make a unique `fixed_point32` type. Since the numeric representation is a binary one, some decimal values may not be exactly representable, but it provides more than 9 decimal digits of precision both before and after the decimal point (18 digits total). For comparison, double precision floating-point has less than 16 decimal digits of precision, so you should be careful about using floating-point to convert these values to decimal. + +### Types + +Represents a fixed-point numeric number with 32 fractional bits. + +```move + struct FixedPoint32; +``` + +### Functions + +Multiply a u64 integer by a fixed-point number, truncating any fractional part of the product. This will abort if the product overflows. + +```move + public fun multiply_u64(val: u64, multiplier: FixedPoint32): u64; +``` + +--------------------------------------------------------------------------- +Divide a u64 integer by a fixed-point number, truncating any fractional part of the quotient. This will abort if the divisor is zero or if the quotient overflows. + +```move + public fun divide_u64(val: u64, divisor: FixedPoint32): u64; +``` + +--------------------------------------------------------------------------- +Create a fixed-point value from a rational number specified by its numerator and denominator. Calling this function should be preferred for using `fixed_point32::create_from_raw_value` which is also available. This will abort if the denominator is zero. It will also abort if the numerator is nonzero and the ratio is not in the range $2^{-32}\ldots2^{32}-1$. When specifying decimal fractions, be careful about rounding errors: if you round to display $N$ digits after the decimal point, you can use a denominator of $10^N$ to avoid numbers where the very small imprecision in the binary representation could change the rounding, e.g., 0.0125 will round down to 0.012 instead of up to 0.013. + +```move + public fun create_from_rational(numerator: u64, denominator: u64): FixedPoint32; +``` + +--------------------------------------------------------------------------- +Create a fixedpoint value from a raw `u64` value. + +```move + public fun create_from_raw_value(value: u64): FixedPoint32; +``` + +--------------------------------------------------------------------------- +Returns `true` if the decimal value of `num` is equal to zero. + +```move + public fun is_zero(num: FixedPoint32): bool; +``` + +--------------------------------------------------------------------------- +Accessor for the raw `u64` value. Other less common operations, such as adding or subtracting `FixedPoint32` values, can be done using the raw values directly. + +```move + public fun get_raw_value(num: FixedPoint32): u64; +``` + +--------------------------------------------------------------------------- diff --git a/vendors/move/crates/documentation/book/src/structs-and-resources.md b/vendors/move/crates/documentation/book/src/structs-and-resources.md new file mode 100644 index 000000000..a073a44cd --- /dev/null +++ b/vendors/move/crates/documentation/book/src/structs-and-resources.md @@ -0,0 +1,527 @@ +# Structs and Resources + +A _struct_ is a user-defined data structure containing typed fields. Structs can store any +non-reference type, including other structs. + +We often refer to struct values as _resources_ if they cannot be copied and cannot be dropped. In +this case, resource values must have ownership transferred by the end of the function. This property +makes resources particularly well served for defining global storage schemas or for representing +important values (such as a token). + +By default, structs are linear and ephemeral. By this we mean that they: cannot be copied, cannot be +dropped, and cannot be stored in global storage. This means that all values have to have ownership +transferred (linear) and the values must be dealt with by the end of the program's execution +(ephemeral). We can relax this behavior by giving the struct [abilities](./abilities.md) which allow +values to be copied or dropped and also to be stored in global storage or to define global storage +schemas. + +## Defining Structs + +Structs must be defined inside a module: + +```move +address 0x2 { +module m { + struct Foo { x: u64, y: bool } + struct Bar {} + struct Baz { foo: Foo, } + // ^ note: it is fine to have a trailing comma +} +} +``` + +Structs cannot be recursive, so the following definition is invalid: + +```move +struct Foo { x: Foo } +// ^ error! Foo cannot contain Foo +``` + +As mentioned above: by default, a struct declaration is linear and ephemeral. So to allow the value +to be used with certain operations (that copy it, drop it, store it in global storage, or use it as +a storage schema), structs can be granted [abilities](./abilities.md) by annotating them with +`has `: + +```move +address 0x2 { +module m { + struct Foo has copy, drop { x: u64, y: bool } +} +} +``` + +For more details, see the [annotating structs](./abilities.md#annotating-structs) section. + +### Naming + +Structs must start with a capital letter `A` to `Z`. After the first letter, struct names can +contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, or digits `0` to `9`. + +```move +struct Foo {} +struct BAR {} +struct B_a_z_4_2 {} +``` + +This naming restriction of starting with `A` to `Z` is in place to give room for future language +features. It may or may not be removed later. + +## Using Structs + +### Creating Structs + +Values of a struct type can be created (or "packed") by indicating the struct name, followed by +value for each field: + +```move +address 0x2 { +module m { + struct Foo has drop { x: u64, y: bool } + struct Baz has drop { foo: Foo } + + fun example() { + let foo = Foo { x: 0, y: false }; + let baz = Baz { foo: foo }; + } +} +} +``` + +If you initialize a struct field with a local variable whose name is the same as the field, you can +use the following shorthand: + +```move +let baz = Baz { foo: foo }; +// is equivalent to +let baz = Baz { foo }; +``` + +This is called sometimes called "field name punning". + +### Destroying Structs via Pattern Matching + +Struct values can be destroyed by binding or assigning them patterns. + +```move +address 0x2 { +module m { + struct Foo { x: u64, y: bool } + struct Bar { foo: Foo } + struct Baz {} + + fun example_destroy_foo() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y: foo_y } = foo; + // ^ shorthand for `x: x` + + // two new bindings + // x: u64 = 3 + // foo_y: bool = false + } + + fun example_destroy_foo_wildcard() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y: _ } = foo; + + // only one new binding since y was bound to a wildcard + // x: u64 = 3 + } + + fun example_destroy_foo_assignment() { + let x: u64; + let y: bool; + Foo { x, y } = Foo { x: 3, y: false }; + + // mutating existing variables x & y + // x = 3, y = false + } + + fun example_foo_ref() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y } = &foo; + + // two new bindings + // x: &u64 + // y: &bool + } + + fun example_foo_ref_mut() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y } = &mut foo; + + // two new bindings + // x: &mut u64 + // y: &mut bool + } + + fun example_destroy_bar() { + let bar = Bar { foo: Foo { x: 3, y: false } }; + let Bar { foo: Foo { x, y } } = bar; + // ^ nested pattern + + // two new bindings + // x: u64 = 3 + // y: bool = false + } + + fun example_destroy_baz() { + let baz = Baz {}; + let Baz {} = baz; + } +} +} +``` + +### Borrowing Structs and Fields + +The `&` and `&mut` operator can be used to create references to structs or fields. These examples +include some optional type annotations (e.g., `: &Foo`) to demonstrate the type of operations. + +```move +let foo = Foo { x: 3, y: true }; +let foo_ref: &Foo = &foo; +let y: bool = foo_ref.y; // reading a field via a reference to the struct +let x_ref: &u64 = &foo.x; + +let x_ref_mut: &mut u64 = &mut foo.x; +*x_ref_mut = 42; // modifying a field via a mutable reference +``` + +It is possible to borrow inner fields of nested structs: + +```move +let foo = Foo { x: 3, y: true }; +let bar = Bar { foo }; + +let x_ref = &bar.foo.x; +``` + +You can also borrow a field via a reference to a struct: + +```move +let foo = Foo { x: 3, y: true }; +let foo_ref = &foo; +let x_ref = &foo_ref.x; +// this has the same effect as let x_ref = &foo.x +``` + +### Reading and Writing Fields + +If you need to read and copy a field's value, you can then dereference the borrowed field: + +```move +let foo = Foo { x: 3, y: true }; +let bar = Bar { foo: copy foo }; +let x: u64 = *&foo.x; +let y: bool = *&foo.y; +let foo2: Foo = *&bar.foo; +``` + +If the field is implicitly copyable, the dot operator can be used to read fields of a struct without +any borrowing. (Only scalar values with the `copy` ability are implicitly copyable.) + +```move +let foo = Foo { x: 3, y: true }; +let x = foo.x; // x == 3 +let y = foo.y; // y == true +``` + +Dot operators can be chained to access nested fields: + +```move +let baz = Baz { foo: Foo { x: 3, y: true } }; +let x = baz.foo.x; // x = 3; +``` + +However, this is not permitted for fields that contain non-primitive types, such a vector or another +struct: + +```move +let foo = Foo { x: 3, y: true }; +let bar = Bar { foo }; +let foo2: Foo = *&bar.foo; +let foo3: Foo = bar.foo; // error! must add an explicit copy with *& +``` + +The reason behind this design decision is that copying a vector or another struct might be an +expensive operation. It is important for a programmer to be aware of this copy and make others aware +with the explicit syntax `*&`. + +In addition reading from fields, the dot syntax can be used to modify fields, regardless of the +field being a primitive type or some other struct. + +```move +let foo = Foo { x: 3, y: true }; +foo.x = 42; // foo = Foo { x: 42, y: true } +foo.y = !foo.y; // foo = Foo { x: 42, y: false } +let bar = Bar { foo }; // bar = Bar { foo: Foo { x: 42, y: false } } +bar.foo.x = 52; // bar = Bar { foo: Foo { x: 52, y: false } } +bar.foo = Foo { x: 62, y: true }; // bar = Bar { foo: Foo { x: 62, y: true } } +``` + +The dot syntax also works via a reference to a struct: + +```move +let foo = Foo { x: 3, y: true }; +let foo_ref = &mut foo; +foo_ref.x = foo_ref.x + 1; +``` + +## Privileged Struct Operations + +Most struct operations on a struct type `T` can only be performed inside the module that declares +`T`: + +- Struct types can only be created ("packed"), destroyed ("unpacked") inside the module that defines + the struct. +- The fields of a struct are only accessible inside the module that defines the struct. + +Following these rules, if you want to modify your struct outside the module, you will need to +provide public APIs for them. The end of the chapter contains some examples of this. + +However, struct _types_ are always visible to another module or script: + +```move +// m.move +address 0x2 { +module m { + struct Foo has drop { x: u64 } + + public fun new_foo(): Foo { + Foo { x: 42 } + } +} +} +``` + +```move +// n.move +address 0x2 { +module n { + use 0x2::m; + + struct Wrapper has drop { + foo: m::Foo + } + + fun f1(foo: m::Foo) { + let x = foo.x; + // ^ error! cannot access fields of `foo` here + } + + fun f2() { + let foo_wrapper = Wrapper { foo: m::new_foo() }; + } +} +} +``` + +Note that structs do not have visibility modifiers (e.g., `public` or `private`). + +## Ownership + +As mentioned above in [Defining Structs](#defining-structs), structs are by default linear and +ephemeral. This means they cannot be copied or dropped. This property can be very useful when +modeling real world resources like money, as you do not want money to be duplicated or get lost in +circulation. + +```move +address 0x2 { +module m { + struct Foo { x: u64 } + + public fun copying_resource() { + let foo = Foo { x: 100 }; + let foo_copy = copy foo; // error! 'copy'-ing requires the 'copy' ability + let foo_ref = &foo; + let another_copy = *foo_ref // error! dereference requires the 'copy' ability + } + + public fun destroying_resource1() { + let foo = Foo { x: 100 }; + + // error! when the function returns, foo still contains a value. + // This destruction requires the 'drop' ability + } + + public fun destroying_resource2(f: &mut Foo) { + *f = Foo { x: 100 } // error! + // destroying the old value via a write requires the 'drop' ability + } +} +} +``` + +To fix the second example (`fun destroying_resource1`), you would need to manually "unpack" the +resource: + +```move +address 0x2 { +module m { + struct Foo { x: u64 } + + public fun destroying_resource1_fixed() { + let foo = Foo { x: 100 }; + let Foo { x: _ } = foo; + } +} +} +``` + +Recall that you are only able to deconstruct a resource within the module in which it is defined. +This can be leveraged to enforce certain invariants in a system, for example, conservation of money. + +If on the other hand, your struct does not represent something valuable, you can add the abilities +`copy` and `drop` to get a struct value that might feel more familiar from other programming +languages: + +```move +address 0x2 { +module m { + struct Foo has copy, drop { x: u64 } + + public fun run() { + let foo = Foo { x: 100 }; + let foo_copy = copy foo; + // ^ this code copies foo, whereas `let x = foo` or + // `let x = move foo` both move foo + + let x = foo.x; // x = 100 + let x_copy = foo_copy.x; // x = 100 + + // both foo and foo_copy are implicitly discarded when the function returns + } +} +} +``` + +## Storing Resources in Global Storage + +Only structs with the `key` ability can be saved directly in +[persistent global storage](./global-storage-operators.md). All values stored within those `key` +structs must have the `store` ability. See the [ability](./abilities) and +[global storage](./global-storage-operators.md) chapters for more detail. + +## Examples + +Here are two short examples of how you might use structs to represent valuable data (in the case of +`Coin`) or more classical data (in the case of `Point` and `Circle`). + +### Example 1: Coin + + + +```move +address 0x2 { +module m { + // We do not want the Coin to be copied because that would be duplicating this "money", + // so we do not give the struct the 'copy' ability. + // Similarly, we do not want programmers to destroy coins, so we do not give the struct the + // 'drop' ability. + // However, we *want* users of the modules to be able to store this coin in persistent global + // storage, so we grant the struct the 'store' ability. This struct will only be inside of + // other resources inside of global storage, so we do not give the struct the 'key' ability. + struct Coin has store { + value: u64, + } + + public fun mint(value: u64): Coin { + // You would want to gate this function with some form of access control to prevent + // anyone using this module from minting an infinite amount of coins. + Coin { value } + } + + public fun withdraw(coin: &mut Coin, amount: u64): Coin { + assert!(coin.balance >= amount, 1000); + coin.value = coin.value - amount; + Coin { value: amount } + } + + public fun deposit(coin: &mut Coin, other: Coin) { + let Coin { value } = other; + coin.value = coin.value + value; + } + + public fun split(coin: Coin, amount: u64): (Coin, Coin) { + let other = withdraw(&mut coin, amount); + (coin, other) + } + + public fun merge(coin1: Coin, coin2: Coin): Coin { + deposit(&mut coin1, coin2); + coin1 + } + + public fun destroy_zero(coin: Coin) { + let Coin { value } = coin; + assert!(value == 0, 1001); + } +} +} +``` + +### Example 2: Geometry + +```move +address 0x2 { +module point { + struct Point has copy, drop, store { + x: u64, + y: u64, + } + + public fun new(x: u64, y: u64): Point { + Point { + x, y + } + } + + public fun x(p: &Point): u64 { + p.x + } + + public fun y(p: &Point): u64 { + p.y + } + + fun abs_sub(a: u64, b: u64): u64 { + if (a < b) { + b - a + } + else { + a - b + } + } + + public fun dist_squared(p1: &Point, p2: &Point): u64 { + let dx = abs_sub(p1.x, p2.x); + let dy = abs_sub(p1.y, p2.y); + dx*dx + dy*dy + } +} +} +``` + +```move +address 0x2 { +module circle { + use 0x2::point::{Self, Point}; + + struct Circle has copy, drop, store { + center: Point, + radius: u64, + } + + public fun new(center: Point, radius: u64): Circle { + Circle { center, radius } + } + + public fun overlaps(c1: &Circle, c2: &Circle): bool { + let d = point::dist_squared(&c1.center, &c2.center); + let r1 = c1.radius; + let r2 = c2.radius; + d*d <= r1*r1 + 2*r1*r2 + r2*r2 + } +} +} +``` diff --git a/vendors/move/crates/documentation/book/src/tuples.md b/vendors/move/crates/documentation/book/src/tuples.md new file mode 100644 index 000000000..1f4575b81 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/tuples.md @@ -0,0 +1,137 @@ +# Tuples and Unit + +Move does not fully support tuples as one might expect coming from another language with them as a +[first-class value](https://en.wikipedia.org/wiki/First-class_citizen). However, in order to support multiple return values, Move has tuple-like +expressions. These expressions do not result in a concrete value at runtime (there are no tuples in +the bytecode), and as a result they are very limited: they can only appear in expressions (usually +in the return position for a function); they cannot be bound to local variables; they cannot be +stored in structs; and tuple types cannot be used to instantiate generics. + +Similarly, [unit `()`](https://en.wikipedia.org/wiki/Unit_type) is a type created by the Move source language in order to be expression based. +The unit value `()` does not result in any runtime value. We can consider unit`()` to be an empty +tuple, and any restrictions that apply to tuples also apply to unit. + +It might feel weird to have tuples in the language at all given these restrictions. But one of the +most common use cases for tuples in other languages is for functions to allow functions to return +multiple values. Some languages work around this by forcing the users to write structs that contain +the multiple return values. However in Move, you cannot put references inside of +[structs](./structs-and-resources.md). This required Move to support multiple return values. These +multiple return values are all pushed on the stack at the bytecode level. At the source level, these +multiple return values are represented using tuples. + +## Literals + +Tuples are created by a comma separated list of expressions inside of parentheses. + +| Syntax | Type | Description | +| --------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------ | +| `()` | `(): ()` | Unit, the empty tuple, or the tuple of arity 0 | +| `(e1, ..., en)` | `(e1, ..., en): (T1, ..., Tn)` where `e_i: Ti` s.t. `0 < i <= n` and `n > 0` | A `n`-tuple, a tuple of arity `n`, a tuple with `n` elements | + +Note that `(e)` does not have type `(e): (t)`, in other words there is no tuple with one element. If +there is only a single element inside of the parentheses, the parentheses are only used for +disambiguation and do not carry any other special meaning. + +Sometimes, tuples with two elements are called "pairs" and tuples with three elements are called +"triples." + +### Examples + +```move +address 0x42 { +module example { + // all 3 of these functions are equivalent + + // when no return type is provided, it is assumed to be `()` + fun returns_unit_1() { } + + // there is an implicit () value in empty expression blocks + fun returns_unit_2(): () { } + + // explicit version of `returns_unit_1` and `returns_unit_2` + fun returns_unit_3(): () { () } + + + fun returns_3_values(): (u64, bool, address) { + (0, false, @0x42) + } + fun returns_4_values(x: &u64): (&u64, u8, u128, vector) { + (x, 0, 1, b"foobar") + } +} +} +``` + +## Operations + +The only operation that can be done on tuples currently is destructuring. + +### Destructuring + +For tuples of any size, they can be destructured in either a `let` binding or in an assignment. + +For example: + +```move +address 0x42 { +module example { + // all 3 of these functions are equivalent + fun returns_unit() {} + fun returns_2_values(): (bool, bool) { (true, false) } + fun returns_4_values(x: &u64): (&u64, u8, u128, vector) { (x, 0, 1, b"foobar") } + + fun examples(cond: bool) { + let () = (); + let (x, y): (u8, u64) = (0, 1); + let (a, b, c, d) = (@0x0, 0, false, b""); + + () = (); + (x, y) = if (cond) (1, 2) else (3, 4); + (a, b, c, d) = (@0x1, 1, true, b"1"); + } + + fun examples_with_function_calls() { + let () = returns_unit(); + let (x, y): (bool, bool) = returns_2_values(); + let (a, b, c, d) = returns_4_values(&0); + + () = returns_unit(); + (x, y) = returns_2_values(); + (a, b, c, d) = returns_4_values(&1); + } +} +} +``` + +For more details, see [Move Variables](./variables.md). + +## Subtyping + +Along with references, tuples are the only types that have [subtyping](https://en.wikipedia.org/wiki/Subtyping) in Move. Tuples do have +subtyping only in the sense that subtype with references (in a covariant way). + +For example: + +```move +let x: &u64 = &0; +let y: &mut u64 = &mut 1; + +// (&u64, &mut u64) is a subtype of (&u64, &u64) +// since &mut u64 is a subtype of &u64 +let (a, b): (&u64, &u64) = (x, y); + +// (&mut u64, &mut u64) is a subtype of (&u64, &u64) +// since &mut u64 is a subtype of &u64 +let (c, d): (&u64, &u64) = (y, y); + +// error! (&u64, &mut u64) is NOT a subtype of (&mut u64, &mut u64) +// since &u64 is NOT a subtype of &mut u64 +let (e, f): (&mut u64, &mut u64) = (x, y); +``` + +## Ownership + +As mentioned above, tuple values don't really exist at runtime. And currently they cannot be stored +into local variables because of this (but it is likely that this feature will come soon). As such, +tuples can only be moved currently, as copying them would require putting them into a local variable +first. diff --git a/vendors/move/crates/documentation/book/src/unit-testing.md b/vendors/move/crates/documentation/book/src/unit-testing.md new file mode 100644 index 000000000..75649da19 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/unit-testing.md @@ -0,0 +1,316 @@ +# Unit Tests + +Unit testing for Move adds three new annotations to the Move source language: + +* `#[test]` +* `#[test_only]`, and +* `#[expected_failure]`. + +They respectively mark a function as a test, mark a module or module member (`use`, function, or struct) as code to be included for testing only, and mark that a test is expected to fail. These annotations can be placed on a function with any visibility. Whenever a module or module member is annotated as `#[test_only]` or `#[test]`, it will not be included in the compiled bytecode unless it is compiled for testing. + +## Testing Annotations: Their Meaning and Usage + +Both the `#[test]` and `#[expected_failure]` annotations can be used either with or without arguments. + +Without arguments, the `#[test]` annotation can only be placed on a function with no parameters. This annotation simply marks this function as a test to be run by the unit testing harness. + +``` +#[test] // OK +fun this_is_a_test() { ... } + +#[test] // Will fail to compile since the test takes an argument +fun this_is_not_correct(arg: signer) { ... } +``` + +A test can also be annotated as an `#[expected_failure]`. This annotation marks that the test should is expected to raise an error. You can ensure that a test is aborting with a specific abort code by annotating it with `#[expected_failure(abort_code = )]`, if it then fails with a different abort code or with a non-abort error the test will fail. Only functions that have the `#[test]` annotation can also be annotated as an #`[expected_failure]`. + +``` +#[test] +#[expected_failure] +public fun this_test_will_abort_and_pass() { abort 1 } + +#[test] +#[expected_failure] +public fun test_will_error_and_pass() { 1/0; } + +#[test] +#[expected_failure(abort_code = 0)] +public fun test_will_error_and_fail() { 1/0; } + +#[test, expected_failure] // Can have multiple in one attribute. This test will pass. +public fun this_other_test_will_abort_and_pass() { abort 1 } +``` + +With arguments, a test annotation takes the form `#[test( =
, ..., =
)]`. If a function is annotated in such a manner, the function's parameters must be a permutation of the parameters <`param_name_1>, ..., `, i.e., the order of these parameters as they occur in the function and their order in the test annotation do not have to be the same, but they must be able to be matched up with each other by name. + +Only parameters with a type of `signer` are supported as test parameters. If a non-`signer` parameter is supplied, the test will result in an error when run. + +``` +#[test(arg = @0xC0FFEE)] // OK +fun this_is_correct_now(arg: signer) { ... } + +#[test(wrong_arg_name = @0xC0FFEE)] // Not correct: arg name doesn't match +fun this_is_incorrect(arg: signer) { ... } + +#[test(a = @0xC0FFEE, b = @0xCAFE)] // OK. We support multiple signer arguments, but you must always provide a value for that argument +fun this_works(a: signer, b: signer) { ... } + +// somewhere a named address is declared +#[test_only] // test-only named addresses are supported +address TEST_NAMED_ADDR = @0x1; +... +#[test(arg = @TEST_NAMED_ADDR)] // Named addresses are supported! +fun this_is_correct_now(arg: signer) { ... } +``` + +An expected failure annotation can also take the form `#[expected_failure(abort_code = )]`. If a test function is annotated in such a way, the test must abort with an abort code equal to ``. Any other failure or abort code will result in a test failure. + +``` +#[test, expected_failure(abort_code = 1)] // This test will fail +fun this_test_should_abort_and_fail() { abort 0 } + +#[test] +#[expected_failure(abort_code = 0)] // This test will pass +fun this_test_should_abort_and_pass_too() { abort 0 } +``` + +A module and any of its members can be declared as test only. In such a case the item will only be included in the compiled Move bytecode when compiled in test mode. Additionally, when compiled outside of test mode, any non-test `use`s of a `#[test_only]` module will raise an error during compilation. + +``` +#[test_only] // test only attributes can be attached to modules +module abc { ... } + +#[test_only] // test only attributes can be attached to named addresses +address ADDR = @0x1; + +#[test_only] // .. to uses +use 0x1::some_other_module; + +#[test_only] // .. to structs +struct SomeStruct { ... } + +#[test_only] // .. and functions. Can only be called from test code, but not a test +fun test_only_function(...) { ... } +``` + +## Running Unit Tests + +Unit tests for a Move package can be run with the [`move test` +command](./packages.md). + +When running tests, every test will either `PASS`, `FAIL`, or `TIMEOUT`. If a test case fails, the location of the failure along with the function name that caused the failure will be reported if possible. You can see an example of this below. + +A test will be marked as timing out if it exceeds the maximum number of instructions that can be executed for any single test. This bound can be changed using the options below, and its default value is set to 5000 instructions. Additionally, while the result of a test is always deterministic, tests are run in parallel by default, so the ordering of test results in a test run is non-deterministic unless running with only one thread (see `OPTIONS` below). + +There are also a number of options that can be passed to the unit testing binary to fine-tune testing and to help debug failing tests. These can be found using the the help flag: + +``` +$ move -h +``` + +## Example + +A simple module using some of the unit testing features is shown in the following example: + +First create an empty package and change directory into it: + +``` +$ move new TestExample; cd TestExample +``` + +Next add the following to the `Move.toml`: + +``` +[dependencies] +MoveStdlib = { git = "https://github.com/diem/diem.git", subdir="language/move-stdlib", rev = "56ab033cc403b489e891424a629e76f643d4fb6b", addr_subst = { "std" = "0x1" } } +``` + +Next add the following module under the `sources` directory: + +``` +// filename: sources/my_module.move +module 0x1::my_module { + + struct MyCoin has key { value: u64 } + + public fun make_sure_non_zero_coin(coin: MyCoin): MyCoin { + assert!(coin.value > 0, 0); + coin + } + + public fun has_coin(addr: address): bool { + exists(addr) + } + + #[test] + fun make_sure_non_zero_coin_passes() { + let coin = MyCoin { value: 1 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test] + // Or #[expected_failure] if we don't care about the abort code + #[expected_failure(abort_code = 0)] + fun make_sure_zero_coin_fails() { + let coin = MyCoin { value: 0 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test_only] // test only helper function + fun publish_coin(account: &signer) { + move_to(account, MyCoin { value: 1 }) + } + + #[test(a = @0x1, b = @0x2)] + fun test_has_coin(a: signer, b: signer) { + publish_coin(&a); + publish_coin(&b); + assert!(has_coin(@0x1), 0); + assert!(has_coin(@0x2), 1); + assert!(!has_coin(@0x3), 1); + } +} +``` + +### Running Tests + +You can then run these tests with the `move test` command: + +``` +$ move test +BUILDING MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +[ PASS ] 0x1::my_module::test_has_coin +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +### Using Test Flags + +#### `-f ` or `--filter ` +This will only run tests whose fully qualified name contains ``. For example if we wanted to only run tests with `"zero_coin"` in their name: + +``` +$ move test -f zero_coin +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +Test result: OK. Total tests: 2; passed: 2; failed: 0 +``` + +#### `-i ` or `--gas_used ` +This bounds the amount of gas that can be consumed for any one test to ``: + +``` +$ move test -i 0 +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ TIMEOUT ] 0x1::my_module::make_sure_non_zero_coin_passes +[ TIMEOUT ] 0x1::my_module::make_sure_zero_coin_fails +[ TIMEOUT ] 0x1::my_module::test_has_coin + +Test failures: + +Failures in 0x1::my_module: + +┌── make_sure_non_zero_coin_passes ────── +│ Test timed out +└────────────────── + + +┌── make_sure_zero_coin_fails ────── +│ Test timed out +└────────────────── + + +┌── test_has_coin ────── +│ Test timed out +└────────────────── + +Test result: FAILED. Total tests: 3; passed: 0; failed: 3 +``` + +#### `-s` or `--statistics` +With these flags you can gather statistics about the tests run and report the runtime and gas used for each test. For example, if we wanted to see the statistics for the tests in the example above: + +``` +$ move test -s +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +[ PASS ] 0x1::my_module::test_has_coin + +Test Statistics: + +┌────────────────────────────────────────────────┬────────────┬───────────────────────────┐ +│ Test Name │ Time │ Gas Used │ +├────────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::my_module::make_sure_non_zero_coin_passes │ 0.009 │ 1 │ +├────────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::my_module::make_sure_zero_coin_fails │ 0.008 │ 1 │ +├────────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::my_module::test_has_coin │ 0.008 │ 1 │ +└────────────────────────────────────────────────┴────────────┴───────────────────────────┘ + +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +#### `-g` or `--state-on-error` +These flags will print the global state for any test failures. e.g., if we added the following (failing) test to the `my_module` example: + +``` +module 0x1::my_module { + ... + #[test(a = @0x1)] + fun test_has_coin_bad(a: signer) { + publish_coin(&a); + assert!(has_coin(@0x1), 0); + assert!(has_coin(@0x2), 1); + } +} +``` + +we would get the following output when running the tests: + +``` +$ move test -g +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +[ PASS ] 0x1::my_module::test_has_coin +[ FAIL ] 0x1::my_module::test_has_coin_bad + +Test failures: + +Failures in 0x1::my_module: + +┌── test_has_coin_bad ────── +│ error[E11001]: test failure +│ ┌─ /home/tzakian/TestExample/sources/my_module.move:47:10 +│ │ +│ 44 │ fun test_has_coin_bad(a: signer) { +│ │ ----------------- In this function in 0x1::my_module +│ · +│ 47 │ assert!(has_coin(@0x2), 1); +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to abort but it aborted with 1 here +│ +│ +│ ────── Storage state at point of failure ────── +│ 0x1: +│ => key 0x1::my_module::MyCoin { +│ value: 1 +│ } +│ +└────────────────── + +Test result: FAILED. Total tests: 4; passed: 3; failed: 1 +``` diff --git a/vendors/move/crates/documentation/book/src/uses.md b/vendors/move/crates/documentation/book/src/uses.md new file mode 100644 index 000000000..5e7edf8d9 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/uses.md @@ -0,0 +1,359 @@ +# Uses and Aliases + +The `use` syntax can be used to create aliases to members in other modules. `use` can be used to +create aliases that last either for the entire module, or for a given expression block scope. + +## Syntax + +There are several different syntax cases for `use`. Starting with the most simple, we have the +following for creating aliases to other modules + +```move +use
::; +use
:: as ; +``` + +For example + +```move +use std::vector; +use std::vector as V; +``` + +`use std::vector;` introduces an alias `vector` for `std::vector`. This means that anywhere you +would want to use the module name `std::vector` (assuming this `use` is in scope), you could use +`vector` instead. `use std::vector;` is equivalent to `use std::vector as vector;` + +Similarly `use std::vector as V;` would let you use `V` instead of `std::vector` + +```move= +use std::vector; +use std::vector as V; + +fun new_vecs(): (vector, vector, vector) { + let v1 = std::vector::empty(); + let v2 = vector::empty(); + let v3 = V::empty(); + (v1, v2, v3) +} +``` + +If you want to import a specific module member (such as a function, struct, or constant). You can +use the following syntax. + +```move +use
::::; +use
:::: as ; +``` + +For example + +```move +use std::vector::empty; +use std::vector::empty as empty_vec; +``` + +This would let you use the function `std::vector::empty` without full qualification. Instead you +could use `empty` and `empty_vec` respectively. Again, `use std::vector::empty;` is equivalent to +`use std::vector::empty as empty;` + +```move= +use std::vector::empty; +use std::vector::empty as empty_vec; + +fun new_vecs(): (vector, vector, vector) { + let v1 = std::vector::empty(); + let v2 = empty(); + let v3 = empty_vec(); + (v1, v2, v3) +} +``` + +If you want to add aliases for multiple module members at once, you can do so with the following +syntax + +```move +use
::::{, as ... }; +``` + +For example + +```move= +use std::vector::{push_back, length as len, pop_back}; + +fun swap_last_two(v: &mut vector) { + assert!(len(v) >= 2, 42); + let last = pop_back(v); + let second_to_last = pop_back(v); + push_back(v, last); + push_back(v, second_to_last) +} +``` + +If you need to add an alias to the Module itself in addition to module members, you can do that in a +single `use` using `Self`. `Self` is a member of sorts that refers to the module. + +```move +use std::vector::{Self, empty}; +``` + +For clarity, all of the following are equivalent: + +```move +use std::vector; +use std::vector as vector; +use std::vector::Self; +use std::vector::Self as vector; +use std::vector::{Self}; +use std::vector::{Self as vector}; +``` + +If needed, you can have as many aliases for any item as you like + +```move= +use std::vector::{ + Self, + Self as V, + length, + length as len, +}; + +fun pop_twice(v: &mut vector): (T, T) { + // all options available given the `use` above + assert!(vector::length(v) > 1, 42); + assert!(V::length(v) > 1, 42); + assert!(length(v) > 1, 42); + assert!(len(v) > 1, 42); + + (vector::pop_back(v), vector::pop_back(v)) +} +``` + +## Inside a `module` + +Inside of a `module` all `use` declarations are usable regardless of the order of declaration. + +```move= +address 0x42 { +module example { + use std::vector; + + fun example(): vector { + let v = empty(); + vector::push_back(&mut v, 0); + vector::push_back(&mut v, 10); + v + } + + use std::vector::empty; +} +} +``` + +The aliases declared by `use` in the module usable within that module. + +Additionally, the aliases introduced cannot conflict with other module members. See +[Uniqueness](#uniqueness) for more details + +## Inside an expression + +You can add `use` declarations to the beginning of any expression block + +```move= +address 0x42 { +module example { + + fun example(): vector { + use std::vector::{empty, push_back}; + + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 10); + v + } +} +} +``` + +As with `let`, the aliases introduced by `use` in an expression block are removed at the end of that +block. + +```move= +address 0x42 { +module example { + + fun example(): vector { + let result = { + use std::vector::{empty, push_back}; + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 10); + v + }; + result + } + +} +} +``` + +Attempting to use the alias after the block ends will result in an error + +```move= +fun example(): vector { + let result = { + use std::vector::{empty, push_back}; + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 10); + v + }; + let v2 = empty(); // ERROR! +// ^^^^^ unbound function 'empty' + result +} +``` + +Any `use` must be the first item in the block. If the `use` comes after any expression or `let`, it +will result in a parsing error + +```move= +{ + let x = 0; + use std::vector; // ERROR! + let v = vector::empty(); +} +``` + +## Naming rules + +Aliases must follow the same rules as other module members. This means that aliases to structs or +constants must start with `A` to `Z` + +```move= +address 0x42 { +module data { + struct S {} + const FLAG: bool = false; + fun foo() {} +} +module example { + use 0x42::data::{ + S as s, // ERROR! + FLAG as fLAG, // ERROR! + foo as FOO, // valid + foo as bar, // valid + }; +} +} +``` + +## Uniqueness + +Inside a given scope, all aliases introduced by `use` declarations must be unique. + +For a module, this means aliases introduced by `use` cannot overlap + +```move= +address 0x42 { +module example { + + use std::vector::{empty as foo, length as foo}; // ERROR! + // ^^^ duplicate 'foo' + + use std::vector::empty as bar; + + use std::vector::length as bar; // ERROR! + // ^^^ duplicate 'bar' + +} +} +``` + +And, they cannot overlap with any of the module's other members + +```move= +address 0x42 { +module data { + struct S {} +} +module example { + use 0x42::data::S; + + struct S { value: u64 } // ERROR! + // ^ conflicts with alias 'S' above +} +} +``` + +Inside of an expression block, they cannot overlap with each other, but they can +[shadow](#shadowing) other aliases or names from an outer scope + +## Shadowing + +`use` aliases inside of an expression block can shadow names (module members or aliases) from the +outer scope. As with shadowing of locals, the shadowing ends at the end of the expression block; + +```move= +address 0x42 { +module example { + + struct WrappedVector { vec: vector } + + fun empty(): WrappedVector { + WrappedVector { vec: std::vector::empty() } + } + + fun example1(): (WrappedVector, WrappedVector) { + let vec = { + use std::vector::{empty, push_back}; + // 'empty' now refers to std::vector::empty + + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 1); + push_back(&mut v, 10); + v + }; + // 'empty' now refers to Self::empty + + (empty(), WrappedVector { vec }) + } + + fun example2(): (WrappedVector, WrappedVector) { + use std::vector::{empty, push_back}; + let w: WrappedVector = { + use 0x42::example::empty; + empty() + }; + push_back(&mut w.vec, 0); + push_back(&mut w.vec, 1); + push_back(&mut w.vec, 10); + + let vec = empty(); + push_back(&mut vec, 0); + push_back(&mut vec, 1); + push_back(&mut vec, 10); + + (w, WrappedVector { vec }) + } +} +} +``` + +## Unused Use or Alias + +An unused `use` will result in an error + +```move= +address 0x42 { +module example { + use std::vector::{empty, push_back}; // ERROR! + // ^^^^^^^^^ unused alias 'push_back' + + fun example(): vector { + empty() + } +} +} +``` diff --git a/vendors/move/crates/documentation/book/src/variables.md b/vendors/move/crates/documentation/book/src/variables.md new file mode 100644 index 000000000..e16738adb --- /dev/null +++ b/vendors/move/crates/documentation/book/src/variables.md @@ -0,0 +1,741 @@ +# Local Variables and Scope + +Local variables in Move are lexically (statically) scoped. New variables are introduced with the +keyword `let`, which will shadow any previous local with the same name. Locals are mutable and can +be updated both directly and via a mutable reference. + +## Declaring Local Variables + +### `let` bindings + +Move programs use `let` to bind variable names to values: + +```move +let x = 1; +let y = x + x: +``` + +`let` can also be used without binding a value to the local. + +```move +let x; +``` + +The local can then be assigned a value later. + +```move +let x; +if (cond) { + x = 1 +} else { + x = 0 +} +``` + +This can be very helpful when trying to extract a value from a loop when a default value cannot be +provided. + +```move +let x; +let cond = true; +let i = 0; +loop { + (x, cond) = foo(i); + if (!cond) break; + i = i + 1; +} +``` + +### Variables must be assigned before use + +Move's type system prevents a local variable from being used before it has been assigned. + +```move +let x; +x + x // ERROR! +``` + +```move +let x; +if (cond) x = 0; +x + x // ERROR! +``` + +```move +let x; +while (cond) x = 0; +x + x // ERROR! +``` + +### Valid variable names + +Variable names can contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, and digits `0` +to `9`. Variable names must start with either an underscore `_` or a letter `a` through `z`. They +_cannot_ start with uppercase letters. + +```move +// all valid +let x = e; +let _x = e; +let _A = e; +let x0 = e; +let xA = e; +let foobar_123 = e; + +// all invalid +let X = e; // ERROR! +let Foo = e; // ERROR! +``` + +### Type annotations + +The type of a local variable can almost always be inferred by Move's type system. However, Move +allows explicit type annotations that can be useful for readability, clarity, or debuggability. The +syntax for adding a type annotation is: + +```move +let x: T = e; // "Variable x of type T is initialized to expression e" +``` + +Some examples of explicit type annotations: + +```move +address 0x42 { +module example { + + struct S { f: u64, g: u64 } + + fun annotated() { + let u: u8 = 0; + let b: vector = b"hello"; + let a: address = @0x0; + let (x, y): (&u64, &mut u64) = (&0, &mut 1); + let S { f, g: f2 }: S = S { f: 0, g: 1 }; + } +} +} +``` + +Note that the type annotations must always be to the right of the pattern: + +```move +let (x: &u64, y: &mut u64) = (&0, &mut 1); // ERROR! should be let (x, y): ... = +``` + +### When annotations are necessary + +In some cases, a local type annotation is required if the type system cannot infer the type. This +commonly occurs when the type argument for a generic type cannot be inferred. For example: + +```move +let _v1 = vector::empty(); // ERROR! +// ^^^^^^^^^^^^^^^ Could not infer this type. Try adding an annotation +let v2: vector = vector::empty(); // no error +``` + +In a rarer case, the type system might not be able to infer a type for divergent code (where all the +following code is unreachable). Both `return` and [`abort`](./abort-and-assert.md) are expressions +and can have any type. A [`loop`](./loops.md) has type `()` if it has a `break`, but if there is no +break out of the `loop`, it could have any type. If these types cannot be inferred, a type +annotation is required. For example, this code: + +```move +let a: u8 = return (); +let b: bool = abort 0; +let c: signer = loop (); + +let x = return (); // ERROR! +// ^ Could not infer this type. Try adding an annotation +let y = abort 0; // ERROR! +// ^ Could not infer this type. Try adding an annotation +let z = loop (); // ERROR! +// ^ Could not infer this type. Try adding an annotation +``` + +Adding type annotations to this code will expose other errors about dead code or unused local +variables, but the example is still helpful for understanding this problem. + +### Multiple declarations with tuples + +`let` can introduce more than one local at a time using tuples. The locals declared inside the +parenthesis are initialized to the corresponding values from the tuple. + +```move +let () = (); +let (x0, x1) = (0, 1); +let (y0, y1, y2) = (0, 1, 2); +let (z0, z1, z2, z3) = (0, 1, 2, 3); +``` + +The type of the expression must match the arity of the tuple pattern exactly. + +```move +let (x, y) = (0, 1, 2); // ERROR! +let (x, y, z, q) = (0, 1, 2); // ERROR! +``` + +You cannot declare more than one local with the same name in a single `let`. + +```move +let (x, x) = 0; // ERROR! +``` + +### Multiple declarations with structs + +`let` can also introduce more than one local at a time when destructuring (or matching against) a +struct. In this form, the `let` creates a set of local variables that are initialized to the values +of the fields from a struct. The syntax looks like this: + +```move +struct T { f1: u64, f2: u64 } +``` + +```move +let T { f1: local1, f2: local2 } = T { f1: 1, f2: 2 }; +// local1: u64 +// local2: u64 +``` + +Here is a more complicated example: + +```move +address 0x42 { +module example { + struct X { f: u64 } + struct Y { x1: X, x2: X } + + fun new_x(): X { + X { f: 1 } + } + + fun example() { + let Y { x1: X { f }, x2 } = Y { x1: new_x(), x2: new_x() }; + assert!(f + x2.f == 2, 42); + + let Y { x1: X { f: f1 }, x2: X { f: f2 } } = Y { x1: new_x(), x2: new_x() }; + assert!(f1 + f2 == 2, 42); + } +} +} +``` + +Fields of structs can serve double duty, identifying the field to bind _and_ the name of the +variable. This is sometimes referred to as punning. + +```move +let X { f } = e; +``` + +is equivalent to: + +```move +let X { f: f } = e; +``` + +As shown with tuples, you cannot declare more than one local with the same name in a single `let`. + +```move +let Y { x1: x, x2: x } = e; // ERROR! +``` + +### Destructuring against references + +In the examples above for structs, the bound value in the let was moved, destroying the struct value +and binding its fields. + +```move +struct T { f1: u64, f2: u64 } +``` + +```move +let T { f1: local1, f2: local2 } = T { f1: 1, f2: 2 }; +// local1: u64 +// local2: u64 +``` + +In this scenario the struct value `T { f1: 1, f2: 2 }` no longer exists after the `let`. + +If you wish instead to not move and destroy the struct value, you can borrow each of its fields. For +example: + +```move +let t = T { f1: 1, f2: 2 }; +let T { f1: local1, f2: local2 } = &t; +// local1: &u64 +// local2: &u64 +``` + +And similarly with mutable references: + +```move +let t = T { f1: 1, f2: 2 }; +let T { f1: local1, f2: local2 } = &mut t; +// local1: &mut u64 +// local2: &mut u64 +``` + +This behavior can also work with nested structs. + +```move +address 0x42 { +module example { + struct X { f: u64 } + struct Y { x1: X, x2: X } + + fun new_x(): X { + X { f: 1 } + } + + fun example() { + let y = Y { x1: new_x(), x2: new_x() }; + + let Y { x1: X { f }, x2 } = &y; + assert!(*f + x2.f == 2, 42); + + let Y { x1: X { f: f1 }, x2: X { f: f2 } } = &mut y; + *f1 = *f1 + 1; + *f2 = *f2 + 1; + assert!(*f1 + *f2 == 4, 42); + } +} +} +``` + +### Ignoring Values + +In `let` bindings, it is often helpful to ignore some values. Local variables that start with `_` +will be ignored and not introduce a new variable + +```move +fun three(): (u64, u64, u64) { + (0, 1, 2) +} +``` + +```move +let (x1, _, z1) = three(); +let (x2, _y, z2) = three(); +assert!(x1 + z1 == x2 + z2, 42); +``` + +This can be necessary at times as the compiler will error on unused local variables + +```move +let (x1, y, z1) = three(); // ERROR! +// ^ unused local 'y' +``` + +### General `let` grammar + +All of the different structures in `let` can be combined! With that we arrive at this general +grammar for `let` statements: + +> _let-binding_ → **let** _pattern-or-list_ _type-annotation__opt_ +> _initializer__opt_ > _pattern-or-list_ → _pattern_ | **(** _pattern-list_ **)** > +> _pattern-list_ → _pattern_ **,**_opt_ | _pattern_ **,** _pattern-list_ > +> _type-annotation_ → **:** _type_ _initializer_ → **=** _expression_ + +The general term for the item that introduces the bindings is a _pattern_. The pattern serves to +both destructure data (possibly recursively) and introduce the bindings. The pattern grammar is as +follows: + +> _pattern_ → _local-variable_ | _struct-type_ **{** _field-binding-list_ **}** > +> _field-binding-list_ → _field-binding_ **,**_opt_ | _field-binding_ **,** +> _field-binding-list_ > _field-binding_ → _field_ | _field_ **:** _pattern_ + +A few concrete examples with this grammar applied: + +```move + let (x, y): (u64, u64) = (0, 1); +// ^ local-variable +// ^ pattern +// ^ local-variable +// ^ pattern +// ^ pattern-list +// ^^^^ pattern-list +// ^^^^^^ pattern-or-list +// ^^^^^^^^^^^^ type-annotation +// ^^^^^^^^ initializer +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ let-binding + + let Foo { f, g: x } = Foo { f: 0, g: 1 }; +// ^^^ struct-type +// ^ field +// ^ field-binding +// ^ field +// ^ local-variable +// ^ pattern +// ^^^^ field-binding +// ^^^^^^^ field-binding-list +// ^^^^^^^^^^^^^^^ pattern +// ^^^^^^^^^^^^^^^ pattern-or-list +// ^^^^^^^^^^^^^^^^^^^^ initializer +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ let-binding +``` + +## Mutations + +### Assignments + +After the local is introduced (either by `let` or as a function parameter), the local can be +modified via an assignment: + +```move +x = e +``` + +Unlike `let` bindings, assignments are expressions. In some languages, assignments return the value +that was assigned, but in Move, the type of any assignment is always `()`. + +```move +(x = e: ()) +``` + +Practically, assignments being expressions means that they can be used without adding a new +expression block with braces (`{`...`}`). + +```move +let x = 0; +if (cond) x = 1 else x = 2; +``` + +The assignment uses the same pattern syntax scheme as `let` bindings: + +```move +address 0x42 { +module example { + struct X { f: u64 } + + fun new_x(): X { + X { f: 1 } + } + + // This example will complain about unused variables and assignments. + fun example() { + let (x, _, z) = (0, 1, 3); + let (x, y, f, g); + + (X { f }, X { f: x }) = (new_x(), new_x()); + assert!(f + x == 2, 42); + + (x, y, z, f, _, g) = (0, 0, 0, 0, 0, 0); + } +} +} +``` + +Note that a local variable can only have one type, so the type of the local cannot change between +assignments. + +```move +let x; +x = 0; +x = false; // ERROR! +``` + +### Mutating through a reference + +In addition to directly modifying a local with assignment, a local can be modified via a mutable +reference `&mut`. + +```move +let x = 0; +let r = &mut x; +*r = 1; +assert!(x == 1, 42); +``` + +This is particularly useful if either: + +(1) You want to modify different variables depending on some condition. + +```move +let x = 0; +let y = 1; +let r = if (cond) &mut x else &mut y; +*r = *r + 1; +``` + +(2) You want another function to modify your local value. + +```move +let x = 0; +modify_ref(&mut x); +``` + +This sort of modification is how you modify structs and vectors! + +```move +let v = vector::empty(); +vector::push_back(&mut v, 100); +assert!(*vector::borrow(&v, 0) == 100, 42); +``` + +For more details, see [Move references](./references.md). + +## Scopes + +Any local declared with `let` is available for any subsequent expression, _within that scope_. +Scopes are declared with expression blocks, `{`...`}`. + +Locals cannot be used outside of the declared scope. + +```move +let x = 0; +{ + let y = 1; +}; +x + y // ERROR! +// ^ unbound local 'y' +``` + +But, locals from an outer scope _can_ be used in a nested scope. + +```move +{ + let x = 0; + { + let y = x + 1; // valid + } +} +``` + +Locals can be mutated in any scope where they are accessible. That mutation survives with the local, +regardless of the scope that performed the mutation. + +```move +let x = 0; +x = x + 1; +assert!(x == 1, 42); +{ + x = x + 1; + assert!(x == 2, 42); +}; +assert!(x == 2, 42); +``` + +### Expression Blocks + +An expression block is a series of statements separated by semicolons (`;`). The resulting value of +an expression block is the value of the last expression in the block. + +```move +{ let x = 1; let y = 1; x + y } +``` + +In this example, the result of the block is `x + y`. + +A statement can be either a `let` declaration or an expression. Remember that assignments (`x = e`) +are expressions of type `()`. + +```move +{ let x; let y = 1; x = 1; x + y } +``` + +Function calls are another common expression of type `()`. Function calls that modify data are +commonly used as statements. + +```move +{ let v = vector::empty(); vector::push_back(&mut v, 1); v } +``` + +This is not just limited to `()` types---any expression can be used as a statement in a sequence! + +```move +{ + let x = 0; + x + 1; // value is discarded + x + 2; // value is discarded + b"hello"; // value is discarded +} +``` + +But! If the expression contains a resource (a value without the `drop` [ability](./abilities.md)), +you will get an error. This is because Move's type system guarantees that any value that is dropped +has the `drop` [ability](./abilities.md). (Ownership must be transferred or the value must be +explicitly destroyed within its declaring module.) + +```move +{ + let x = 0; + Coin { value: x }; // ERROR! +// ^^^^^^^^^^^^^^^^^ unused value without the `drop` ability + x +} +``` + +If a final expression is not present in a block---that is, if there is a trailing semicolon `;`, +there is an implicit [unit `()` value](https://en.wikipedia.org/wiki/Unit_type). Similarly, if the expression block is empty, there is an +implicit unit `()` value. + +```move +// Both are equivalent +{ x = x + 1; 1 / x; } +{ x = x + 1; 1 / x; () } +``` + +```move +// Both are equivalent +{ } +{ () } +``` + +An expression block is itself an expression and can be used anyplace an expression is used. (Note: +The body of a function is also an expression block, but the function body cannot be replaced by +another expression.) + +```move +let my_vector: vector> = { + let v = vector::empty(); + vector::push_back(&mut v, b"hello"); + vector::push_back(&mut v, b"goodbye"); + v +}; +``` + +(The type annotation is not needed in this example and only added for clarity.) + +### Shadowing + +If a `let` introduces a local variable with a name already in scope, that previous variable can no +longer be accessed for the rest of this scope. This is called _shadowing_. + +```move +let x = 0; +assert!(x == 0, 42); + +let x = 1; // x is shadowed +assert!(x == 1, 42); +``` + +When a local is shadowed, it does not need to retain the same type as before. + +```move +let x = 0; +assert!(x == 0, 42); + +let x = b"hello"; // x is shadowed +assert!(x == b"hello", 42); +``` + +After a local is shadowed, the value stored in the local still exists, but will no longer be +accessible. This is important to keep in mind with values of types without the +[`drop` ability](./abilities.md), as ownership of the value must be transferred by the end of the +function. + +```move +address 0x42 { + module example { + struct Coin has store { value: u64 } + + fun unused_resource(): Coin { + let x = Coin { value: 0 }; // ERROR! +// ^ This local still contains a value without the `drop` ability + x.value = 1; + let x = Coin { value: 10 }; + x +// ^ Invalid return + } + } +} +``` + +When a local is shadowed inside a scope, the shadowing only remains for that scope. The shadowing is +gone once that scope ends. + +```move +let x = 0; +{ + let x = 1; + assert!(x == 1, 42); +}; +assert!(x == 0, 42); +``` + +Remember, locals can change type when they are shadowed. + +```move +let x = 0; +{ + let x = b"hello"; + assert!(x = b"hello", 42); +}; +assert!(x == 0, 42); +``` + +## Move and Copy + +All local variables in Move can be used in two ways, either by `move` or `copy`. If one or the other +is not specified, the Move compiler is able to infer whether a `copy` or a `move` should be used. +This means that in all of the examples above, a `move` or a `copy` would be inserted by the +compiler. A local variable cannot be used without the use of `move` or `copy`. + +`copy` will likely feel the most familiar coming from other programming languages, as it creates a +new copy of the value inside of the variable to use in that expression. With `copy`, the local +variable can be used more than once. + +```move +let x = 0; +let y = copy x + 1; +let z = copy x + 2; +``` + +Any value with the `copy` [ability](./abilities.md) can be copied in this way. + +`move` takes the value out of the local variable _without_ copying the data. After a `move` occurs, +the local variable is unavailable. + +```move +let x = 1; +let y = move x + 1; +// ------ Local was moved here +let z = move x + 2; // Error! +// ^^^^^^ Invalid usage of local 'x' +y + z +``` + +### Safety + +Move's type system will prevent a value from being used after it is moved. This is the same safety +check described in [`let` declaration](#let-bindings) that prevents local variables from being used +before it is assigned a value. + + + +### Inference + +As mentioned above, the Move compiler will infer a `copy` or `move` if one is not indicated. The +algorithm for doing so is quite simple: + +- Any scalar value with the `copy` [ability](./abilities.md) is given a `copy`. +- Any reference (both mutable `&mut` and immutable `&`) is given a `copy`. + - Except under special circumstances where it is made a `move` for predictable borrow checker + errors. +- Any other value is given a `move`. + - This means that even though other values might be have the `copy` [ability](./abilities.md), it + must be done _explicitly_ by the programmer. + - This is to prevent accidental copies of large data structures. + +For example: + +```move +let s = b"hello"; +let foo = Foo { f: 0 }; +let coin = Coin { value: 0 }; + +let s2 = s; // move +let foo2 = foo; // move +let coin2 = coin; // move + +let x = 0; +let b = false; +let addr = @0x42; +let x_ref = &x; +let coin_ref = &mut coin2; + +let x2 = x; // copy +let b2 = b; // copy +let addr2 = @0x42; // copy +let x_ref2 = x_ref; // copy +let coin_ref2 = coin_ref; // copy +``` diff --git a/vendors/move/crates/documentation/book/src/vector.md b/vendors/move/crates/documentation/book/src/vector.md new file mode 100644 index 000000000..ad18a7e91 --- /dev/null +++ b/vendors/move/crates/documentation/book/src/vector.md @@ -0,0 +1,169 @@ +# Vector + +`vector` is the only primitive collection type provided by Move. A `vector` is a homogenous +collection of `T`'s that can grow or shrink by pushing/popping values off the "end". + +A `vector` can be instantiated with any type `T`. For example, `vector`, `vector
`, +`vector<0x42::MyModule::MyResource>`, and `vector>` are all valid vector types. + +## Literals + +### General `vector` Literals + +Vectors of any type can be created with `vector` literals. + +| Syntax | Type | Description | +| --------------------- | ----------------------------------------------------------------------------- | ------------------------------------------ | +| `vector[]` | `vector[]: vector` where `T` is any single, non-reference type | An empty vector | +| `vector[e1, ..., en]` | `vector[e1, ..., en]: vector` where `e_i: T` s.t. `0 < i <= n` and `n > 0` | A vector with `n` elements (of length `n`) | + +In these cases, the type of the `vector` is inferred, either from the element type or from the +vector's usage. If the type cannot be inferred, or simply for added clarity, the type can be +specified explicitly: + +```move +vector[]: vector +vector[e1, ..., en]: vector +``` + +#### Example Vector Literals + +```move +(vector[]: vector); +(vector[0u8, 1u8, 2u8]: vector); +(vector[]: vector); +(vector
[@0x42, @0x100]: vector
); +``` + +### `vector` literals + +A common use-case for vectors in Move is to represent "byte arrays", which are represented with +`vector`. These values are often used for cryptographic purposes, such as a public key or a hash +result. These values are so common that specific syntax is provided to make the values more +readable, as opposed to having to use `vector[]` where each individual `u8` value is specified in +numeric form. + +There are currently two supported types of `vector` literals, *byte strings* and *hex strings*. + +#### Byte Strings + +Byte strings are quoted string literals prefixed by a `b`, e.g. `b"Hello!\n"`. + +These are ASCII encoded strings that allow for escape sequences. Currently, the supported escape +sequences are: + +| Escape Sequence | Description | +| --------------- | ---------------------------------------------- | +| `\n` | New line (or Line feed) | +| `\r` | Carriage return | +| `\t` | Tab | +| `\\` | Backslash | +| `\0` | Null | +| `\"` | Quote | +| `\xHH` | Hex escape, inserts the hex byte sequence `HH` | + +#### Hex Strings + +Hex strings are quoted string literals prefixed by a `x`, e.g. `x"48656C6C6F210A"`. + +Each byte pair, ranging from `00` to `FF`, is interpreted as hex encoded `u8` value. So each byte +pair corresponds to a single entry in the resulting `vector`. + +#### Example String Literals + +```move +script { +fun byte_and_hex_strings() { + assert!(b"" == x"", 0); + assert!(b"Hello!\n" == x"48656C6C6F210A", 1); + assert!(b"\x48\x65\x6C\x6C\x6F\x21\x0A" == x"48656C6C6F210A", 2); + assert!( + b"\"Hello\tworld!\"\n \r \\Null=\0" == + x"2248656C6C6F09776F726C6421220A200D205C4E756C6C3D00", + 3 + ); +} +} +``` + +## Operations + +`vector` supports the following operations via the `std::vector` module in the Move standard +library: + +| Function | Description | Aborts? | +| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `vector::empty(): vector` | Create an empty vector that can store values of type `T` | Never | +| `vector::singleton(t: T): vector` | Create a vector of size 1 containing `t` | Never | +| `vector::push_back(v: &mut vector, t: T)` | Add `t` to the end of `v` | Never | +| `vector::pop_back(v: &mut vector): T` | Remove and return the last element in `v` | If `v` is empty | +| `vector::borrow(v: &vector, i: u64): &T` | Return an immutable reference to the `T` at index `i` | If `i` is not in bounds | +| `vector::borrow_mut(v: &mut vector, i: u64): &mut T` | Return a mutable reference to the `T` at index `i` | If `i` is not in bounds | +| `vector::destroy_empty(v: vector)` | Delete `v` | If `v` is not empty | +| `vector::append(v1: &mut vector, v2: vector)` | Add the elements in `v2` to the end of `v1` | Never | +| `vector::contains(v: &vector, e: &T): bool` | Return true if `e` is in the vector `v`. Otherwise, returns false | Never | +| `vector::swap(v: &mut vector, i: u64, j: u64)` | Swaps the elements at the `i`th and `j`th indices in the vector `v` | If `i` or `j` is out of bounds | +| `vector::reverse(v: &mut vector)` | Reverses the order of the elements in the vector `v` in place | Never | +| `vector::index_of(v: &vector, e: &T): (bool, u64)` | Return `(true, i)` if `e` is in the vector `v` at index `i`. Otherwise, returns `(false, 0)` | Never | +| `vector::remove(v: &mut vector, i: u64): T` | Remove the `i`th element of the vector `v`, shifting all subsequent elements. This is O(n) and preserves ordering of elements in the vector | If `i` is out of bounds | +| `vector::swap_remove(v: &mut vector, i: u64): T` | Swap the `i`th element of the vector `v` with the last element and then pop the element, This is O(1), but does not preserve ordering of elements in the vector | If `i` is out of bounds | + +More operations may be added over time. + +## Example + +```move +use std::vector; + +let v = vector::empty(); +vector::push_back(&mut v, 5); +vector::push_back(&mut v, 6); + +assert!(*vector::borrow(&v, 0) == 5, 42); +assert!(*vector::borrow(&v, 1) == 6, 42); +assert!(vector::pop_back(&mut v) == 6, 42); +assert!(vector::pop_back(&mut v) == 5, 42); +``` + +## Destroying and copying `vector`s + +Some behaviors of `vector` depend on the abilities of the element type, `T`. For example, vectors +containing elements that do not have `drop` cannot be implicitly discarded like `v` in the example +above--they must be explicitly destroyed with `vector::destroy_empty`. + +Note that `vector::destroy_empty` will abort at runtime unless `vec` contains zero elements: + +```move +fun destroy_any_vector(vec: vector) { + vector::destroy_empty(vec) // deleting this line will cause a compiler error +} +``` + +But no error would occur for dropping a vector that contains elements with `drop`: + +```move +fun destroy_droppable_vector(vec: vector) { + // valid! + // nothing needs to be done explicitly to destroy the vector +} +``` + +Similarly, vectors cannot be copied unless the element type has `copy`. In other words, a +`vector` has `copy` if and only if `T` has `copy`. However, even copyable vectors are never +implicitly copied: + +```move +let x = vector::singleton(10); +let y = copy x; // compiler error without the copy! +``` + +Copies of large vectors can be expensive, so the compiler requires explicit `copy`'s to make it +easier to see where they are happening. + +For more details see the sections on [type abilities](./abilities.md) and [generics](./generics.md). + +## Ownership + +As mentioned [above](#destroying-and-copying-vectors), `vector` values can be copied only if the +elements can be copied. In that case, the copy must be explicit via a +[`copy`](./variables.md#move-and-copy) or a [dereference `*`](./references.md#reading-and-writing-through-references). diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/.gitignore b/vendors/move/crates/documentation/book/translations/move-book-zh/.gitignore new file mode 100644 index 000000000..7585238ef --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/.gitignore @@ -0,0 +1 @@ +book diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/CONTRIBUTING.md b/vendors/move/crates/documentation/book/translations/move-book-zh/CONTRIBUTING.md new file mode 100644 index 000000000..8d7724ea5 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/CONTRIBUTING.md @@ -0,0 +1,74 @@ +# Contributing to Move Book Chinese Version + +感谢您有兴趣为**《Move Book 中文版》**做出贡献!有很多方法可以做出贡献,我们感谢所有这些方式。 + +本翻译项目由 [*Move 中文社区(MoveCC)*](https://github.com/move-cc)[发起](https://github.com/move-language/move/issues/353),并与 [MoveDAO 社区](https://github.com/move-dao)共同初步完善。 + +目前工作仍在进行中! + +欢迎所有对 Move 感兴趣的朋友一起加入到《Move Book 中文版》的翻译工作中。 + +## 提交 PR 的 Commits 格式 + +```text +[move-book-zh] 关于这个 PR 的描述信息 +``` + +## 文档规范 + +请参考:[中文技术文档的写作规范](https://github.com/ruanyf/document-style-guide) + +### 断句 + +本书使用 Markdown 作为源文件,使用 [mdBook](https://github.com/rust-lang/mdBook) 作为渲染引擎。 + +由于中英文有所区别,换行后渲染引擎会自动追加一个空格。为了优化视觉体验,中文一个段落内不必换行,保持中文的段内容为一个物理行。 + +英文是由空格分隔的文本,所以不存在上述问题。 + +### 中英文混排规范 + +文中出现中英文混排时,中文与英文之间需要添加一个空格。如果英文单词结尾,此时单词与标点符号之间不添加空格。 + +### 数字规范 + +数字之间需要添加一个空格,如果数字带有英文单位,那么数字与英文单位之间不能添加空格。如果数字后带有中文单位,需要添加一个空格。 + +```text +正确:如果一个 1s 的帧被划分为 10 个时隙,每个时隙为 100ms。 + +错误:如果一个1s的帧被划分为10个时隙,每个时隙为100ms。 + +错误:如果一个 1 s 的帧被划分为10个时隙,每个时隙为 100 ms。 +``` + +### 逗号问题 + +英文中,没有顿号这种标点符号,逗号常用分隔并列的句子成分或结构。 + +英文中,像 `and` 并列词的前面通常会有一个 `,`,但在中文里表示对象之间的并列关系时,`和`的前面不能带逗号。 + +```text +War, famine, and flood are terrible. +战争, 饥荒和洪水都是很可怕的。 +``` + +### 冒号和逗号的使用场景规范 + +冒号通常用在“问、答、说、指出、宣布、证明、表明、例如”一类动词后面,表示提起下文。 +如果在较短的提示句子中,需要将 `:` 改为 `,`;如果提示内容比较多,则使用 `:` 来提起下文: + +示例1,提起的内容短少: + +```text +十六进制字符串是以 x 为前缀的带引号的字符串文字,例如x'48656C6C6F210A' +``` + +示例2,提起的内容多: + +```text +在这些情况下,vector 的类型是从元素类型或从动态数组的使用上推断出来的。如果无法推断类型或者只是为了更清楚地表示,则可以显式指定类型: + +vector[]: vector +vector[e1, ..., en]: vector +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/README.md b/vendors/move/crates/documentation/book/translations/move-book-zh/README.md new file mode 100644 index 000000000..9de276331 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/README.md @@ -0,0 +1,73 @@ +## 参与贡献的重要提示 + +《Move Book 中文版》翻译工作还在持续进行中,如果你愿意贡献你的一份力量,欢迎提交 pr 或 issue。 + +为了方便翻译工作的进行,在提交 pr 时请不要删除英文原文的内容! + +在贡献之前请阅读[官方的贡献指南](https://github.com/move-language/move/blob/main/CONTRIBUTING.md)和[《Move Book 中文版》的贡献指南](./CONTRIBUTING.md)。 + +# Move Book 中文版 + +区块链技术的发展经历了两个阶段,比特币(BTC)开启了*区块链1.0时代*,以太坊(ETH)开启了*区块链2.0时代*。 +以太坊的出现为区块链带来了*智能合约*这一关键技术,让区块链不只停留在记账这一单的目的,而是带来更多的应用拓展性。 +遗憾的是,智能合约如同一把双刃剑,在带来众多丰富功能拓展的同时,也容易让智能合约开发者无意间引入不安全的代码,让链的资产受到威胁。 + +编写简单、安全、易部署的智能合约应该是*区块链3.0时代*应该关注的重点,**面向资源编程**的 [Move 语言](https://github.com/move-language/move),无疑给这个问题提供了一个很好的解决方案。 + +本书是 [Move Book](https://move-language.github.io/move/) 的中文版。 + +## 快速开始 + +本书使用 [mdBook](https://rust-lang.github.io/mdBook/) 构建。 + +1. 使用 Cargo 安装 mdBook: + +```shell +cargo install mdbook +``` + +2. 下载 + +```shell +git clone https://github.com/move-language/move.git +``` + +3. 构建并预览 + +```shell +cd language/documentation/book/translations/move-book-zh +mdbook serve --open +``` + +## Contributors ✨ + +[各章节译者](Translators.md) + +Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + + + + + + + + + + + + + + + + + + + +

zhang

💻 📖 🌍 🚇

ruyisu

💻 🌍 📖 🚇

lshoo

💻 🌍 📖 🤔 👀

Container

💻 🌍 📖 👀

nosalt

💻 🌍 📖 🚇

geometryolife

💻 🌍 📢

666thi

💻 🌍 📢

MagicGordon

💻 🌍 📢

xixifusi1984

💻 🌍 📢

yvvw

💻 🌍 📢

xiaochuan891102

💻 🌍 📢

stephenLee

💻 🌍 📢
+ + + + + diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/Translators.md b/vendors/move/crates/documentation/book/translations/move-book-zh/Translators.md new file mode 100644 index 000000000..35bce4ce5 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/Translators.md @@ -0,0 +1,30 @@ +| | 章节 | 译者 | 校对 | +|----|----------------------------|------------------------------------------------|-------------------------------------------------------------------------------------| +| 0 | Intoduction | Tom | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 1 | Modules and Scripts | [@Kusou1](https://github.com/kusou1) | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 2 | Move Tutorial | loadi、[@leego](https://github.com/leego) | [@Joe Chen](https://github.com/geometryolife) | +| 3 | Integers | Tom | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 4 | Bool | Tom | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 5 | Address | ([@stephenLee](https://github.com/stephenLee)) | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 6 | Vector | ([@stephenLee](https://github.com/stephenLee)) | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 7 | Signer | ([@stephenLee](https://github.com/stephenLee)) | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 8 | References | container | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 9 | Tuples and Unit | container | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 10 | Local Variables and Scopes | @ruyisu | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 11 | Equality | @ruyisu | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 12 | Abort and Assert | @ruyisu | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 13 | Conditionals | [@Kusou1](https://github.com/kusou1) | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 14 | While and Loop | [@Kusou1](https://github.com/kusou1) | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 15 | Functions | @nosalt99 | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 16 | Structs and Resource | @nosalt99 | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 17 | Constants | @nosalt99 | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 18 | Generics | 小川 | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 19 | Type Abilities | 小川 | [@lshoo](https://github.com/lshoo)、[@Joe Chen](https://github.com/geometryolife) | +| 20 | Uses and Aliases | 小川 | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | +| 21 | Friends | @xiaochuan891102 | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | +| 22 | Packages | @xiaochuan891102 | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | +| 23 | Unit Test | [@yvvw](https://github.com/yvvw) | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | +| 24 | Global Storage Structure | [@yvvw](https://github.com/yvvw) | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | +| 25 | Global Storage Operators | [@yvvw](https://github.com/yvvw) | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | +| 26 | Standard Library | @MagicGordon | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | +| 27 | Coding Conventions | @MagicGordon | [@ruyisu](https://github.com/ruy1su)、[@Joe Chen](https://github.com/geometryolife) | diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/book.toml b/vendors/move/crates/documentation/book/translations/move-book-zh/book.toml new file mode 100644 index 000000000..1f51aef58 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/book.toml @@ -0,0 +1,7 @@ +[book] +authors = ["The Move Contributors"] +description = "Move book maintained by the Move Chinese contributors." +language = "zh" +multilingual = false +src = "src" +title = "Move Book 中文版" diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/SUMMARY.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/SUMMARY.md new file mode 100644 index 000000000..4b75899b4 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/SUMMARY.md @@ -0,0 +1,45 @@ +# The Move Programming Language + +[引言(Introduction)](introduction.md) + +## Getting Started + +- [模块和脚本(Modules and Scripts)](modules-and-scripts.md) +- [Move 教程(Move Tutorial)](move-tutorial.md) + +## Primitive Types + +- [整数(Integers)](integers.md) +- [布尔类型(Bool)](bool.md) +- [地址(Address)](address.md) +- [向量(Vector)](vector.md) +- [签名(Signer)](signer.md) +- [引用(References)](references.md) +- [元组和单值(Tuples and Unit)](tuples.md) + +## Basic Concepts + +- [局部变量和作用域(Local Variables and Scopes)](variables.md) +- [等式(Equality)](equality.md) +- [中止和断言(Abort and Assert)](abort-and-assert.md) +- [条件语句(Conditionals)](conditionals.md) +- [循环(While and Loop)](loops.md) +- [函数(Functions)](functions.md) +- [结构体和资源(Structs and Resources)](structs-and-resources.md) +- [常量(Constants)](constants.md) +- [泛型(Generics)](generics.md) +- [类型能力(Type Abilities)](abilities.md) +- [导入和别名(Uses and Aliases)](uses.md) +- [友元函数(Friends)](friends.md) +- [程序包(Packages)](packages.md) +- [单元测试(Unit Tests)](unit-testing.md) + +## Global Storage + +- [全局存储结构(Global Storage Structure)](global-storage-structure.md) +- [全局存储操作(Global Storage Operators)](global-storage-operators.md) + +## Reference + +- [标准库(Standard Library)](standard-library.md) +- [Move 编码约定(Coding Conventions)](coding-conventions.md) diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/abilities.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/abilities.md new file mode 100644 index 000000000..440362288 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/abilities.md @@ -0,0 +1,321 @@ +# 能力 (abilities) + +Abilities are a typing feature in Move that control what actions are permissible for values of a given type. This system grants fine grained control over the "linear" typing behavior of values, as well as if and how values are used in global storage. This is implemented by gating access to certain bytecode instructions so that for a value to be used with the bytecode instruction, it must have the ability required (if one is required at all—not every instruction is gated by an ability). + +能力是 Move 语言中的一种类型特性,用于控制对给定类型的值允许哪些操作。 该系统对值的“线性”类型行为以及值如何在全局存储中使用提供细粒度控制。这是通过对某些字节码指令的进行访问控制来实现的,因此对于要与字节码指令一起使用的值,它必须具有所需的能力(如果需要的话,并非每条指令都由能力控制) + +## 四种能力 (The Four Abilities) + +The four abilities are: + +* [`copy`](#copy) + * Allows values of types with this ability to be copied. +* [`drop`](#drop) + * Allows values of types with this ability to be popped/dropped. +* [`store`](#store) + * Allows values of types with this ability to exist inside a struct in global storage. +* [`key`](#key) + * Allows the type to serve as a key for global storage operations. + +这四种能力分别是: + +* [`copy`](#copy) 复制 + * 允许此类型的值被复制 + +* [`drop`](#drop) 丢弃 + * 允许此类型的值被弹出/丢弃 + +* [`store`](#store) 存储 + * 允许此类型的值存在于全局存储的某个结构体中 + +* [`key`](#key) 键值 + * 允许此类型作为全局存储中的键(具有 `key` 能力的类型才能保存到全局存储中) + + +### `copy` + +The `copy` ability allows values of types with that ability to be copied. It gates the ability to copy values out of local variables with the [`copy`](./variables.md#move-and-copy) operator and to copy values via references with [dereference `*e`](./references.md#reading-and-writing-through-references). + +If a value has `copy`, all values contained inside of that value have `copy`. + +`copy` 能力允许具有此能力的类型的值被复制。 它限制了从本地变量通过 [`copy`](./variables.md#.move-and-copy)能力复制值以及通过 [`dereference *e`](./references.html#reading-and-writing-through-references)复制值这两种情况之外的复制操作。 + +如果一个值具有 `copy` 能力,那么这个值内部的所有值都有 `copy` 能力。 + +### `drop` + +The `drop` ability allows values of types with that ability to be dropped. By dropped, we mean that value is not transferred and is effectively destroyed as the Move program executes. As such, this ability gates the ability to ignore values in a multitude of locations, including: +* not using the value in a local variable or parameter +* not using the value in a [sequence via `;`](./variables.md#expression-blocks) +* overwriting values in variables in [assignments](./variables.md#assignments) +* overwriting values via references when [writing `*e1 = e2`](./references.md#reading-and-writing-through-references). + +If a value has `drop`, all values contained inside of that value have `drop`. + +`drop` 能力允许类型的值被丢弃。丢弃的意思程序执行后值会被有效的销毁而不必被转移。因此,这个能力限制在多个位置忽略使用值的可能性,包括: +* 未被使用的局部变量或者参数 +* 未被使用的 [`sequence` via `;`](./variables.md#expression-blocks)中的值 +* 覆盖[赋值(assignments)](./variables.html#assignments)变量中的值 +* [写入(writing) `*e1 = e2`](https://move-language.github.io/move/references.html#reading-and-writing-through-references) 时通过引用覆盖的值。 + +如果一个值具有 `drop` 能力,那么这个值内部的所有值都有 `drop` 能力。 + +### `store` + +The `store` ability allows values of types with this ability to exist inside of a struct (resource) in global storage, *but* not necessarily as a top-level resource in global storage. This is the only ability that does not directly gate an operation. Instead it gates the existence in global storage when used in tandem with `key`. + +If a value has `store`, all values contained inside of that value have `store` + +`store` 能力允许具有这种能力的类型的值位于[全局存储](./global-storage-operators.html)中的结构体(资源)内, *但不一定是* 全局存储中的顶级资源。这是唯一不直接限制操作的能力。相反,当(`store`)与 `key` 一起使用时,它对全局存储中的可行性进行把关。。 + +如果一个值具有 `store` 能力,那么这个值内部的所有值都有 `store` 能力。 + +### `key` + +The `key` ability allows the type to serve as a key for [global storage operations](./global-storage-operators.md). It gates all global storage operations, so in order for a type to be used with `move_to`, `borrow_global`, `move_from`, etc., the type must have the `key` ability. Note that the operations still must be used in the module where the `key` type is defined (in a sense, the operations are private to the defining module). + +If a value has `key`, all values contained inside of that value have `store`. This is the only ability with this sort of asymmetry. + +`key` 能力允许此类型作为[全局存储](./global-storage-operators.html)中的键。它会限制所有[全局存储](./global-storage-operators.html)中的操作,因此一个类型如果与 `move_to`, `borrow_global`, `move_from` 等一起使用,那么这个类型必须具备 `key` 能力。请注意,这些操作仍然必须在定义 `key` 类型的模块中使用(从某种意义上说,这些操作是此模块的私有操作)。 + +如果有一个值有 `key` 能力,那么这个值包含的所有字段值也都具有 `store` 能力,`key` 能力是唯一一个具有非对称的能力。 + +## Builtin Types (内置类型) + + +Most primitive, builtin types have `copy`, `drop`, and `store` with the exception of `signer`, which just has `store` + +* `bool`, `u8`, `u64`, `u128`, and `address` all have `copy`, `drop`, and `store`. +* `signer` has `drop` + * Cannot be copied and cannot be put into global storage +* `vector` may have `copy`, `drop`, and `store` depending on the abilities of `T`. + * See [Conditional Abilities and Generic Types](#conditional-abilities-and-generic-types) for more details. +* Immutable references `&` and mutable references `&mut` both have `copy` and `drop`. + * This refers to copying and dropping the reference itself, not what they refer to. + * References cannot appear in global storage, hence they do not have `store`. + +None of the primitive types have `key`, meaning none of them can be used directly with the [global storage operations](./global-storage-operators.md). + +几乎所有内置的基本类型具都有 `copy`,`drop`,以及 `store` 能力,`singer` 除外,它只有 `drop` 能力(原文是 `store` 有误,译者注) + +* `bool`, `u8`, `u64`, `u128`, `address` 都具有 `copy`, `drop`, 以及 `store` 能力。 +* `signer` 具有 `drop` 能力。 不能被复制以及不能被存放在全局存储中 +* `vector` 可能具有 `copy`,`drop`,以及`store` 能力,这依赖于 `T` 具有的能力。 查看 [条件能力与泛型类型](#conditional-abilities-and-generic-types)获取详情 +* 不可变引用 `&` 和可变引用 `&mut` 都具有 `copy` 和 `drop` 能力。 + * 这是指复制和删除引用本身,而不是它们所引用的内容。 + * 引用不能出现在全局存储中,因此它们没有 `store` 能力。 + +所有基本类型都没有 `key`,这意味着它们都不能直接用于[全局存储操作](./global-storage-operators.html)。 + +## Annotating Structs (标注结构体) + +To declare that a `struct` has an ability, it is declared with `has ` after the struct name but before the fields. For example: + +要声明一个 `struct` 具有某个能力,它在结构体名称之后, 在字段之前用 `has ` 声明。例如: + +```move +struct Ignorable has drop { f: u64 } +struct Pair has copy, drop, store { x: u64, y: u64 } +``` + +In this case: `Ignorable` has the `drop` ability. `Pair` has `copy`, `drop`, and `store`. + +在这个例子中:`Ignorable` 具有 `drop` 能力。 `Pair` 具有 `copy`、`drop` 和 `store` 能力。 + +All of these abilities have strong guarantees over these gated operations. The operation can be performed on the value only if it has that ability; even if the value is deeply nested inside of some other collection! + +所有这些能力对这些访问操作都有强有力的保证。只有具有该能力,才能对值执行对应的操作;即使该值深层嵌套在其他集合中! + +As such: when declaring a struct’s abilities, certain requirements are placed on the fields. All fields must satisfy these constraints. These rules are necessary so that structs satisfy the reachability rules for the abilities given above. If a struct is declared with the ability... + +* `copy`, all fields must have `copy`. +* `drop`, all fields must have `drop`. +* `store`, all fields must have `store`. +* `key`, all fields must have `store`. + * `key` is the only ability currently that doesn’t require itself. + +因此:在声明结构体的能力时,对字段提出了某些要求。所有字段都必须满足这些约束。这些规则是必要的,以便结构体满足上述功能的可达性规则。如果一个结构被声明为具有某能力: + +* `copy`, 所有的字段必须具有 `copy` 能力。 +* `drop`,所有的字段必须具有 `drop` 能力。 +* `store`,所有的字段必须具有 `store` 能力。 +* `key`,所有的字段必须具有 `store` 能力。`key` 是目前唯一不需要包含自身的能力。 + +例如: + +```move +// A struct without any abilities +struct NoAbilities {} + +struct WantsCopy has copy { + f: NoAbilities, // ERROR 'NoAbilities' does not have 'copy' +} +``` + +and similarly: + +类似的: + +```move +// A struct without any abilities +struct NoAbilities {} + +struct MyResource has key { + f: NoAbilities, // Error 'NoAbilities' does not have 'store' +} +``` + +## Conditional Abilities and Generic Types (条件能力与泛型类型) + +When abilities are annotated on a generic type, not all instances of that type are guaranteed to have that ability. Consider this struct declaration: + +在泛型类型上标注能力时,并非该类型的所有实例都保证具有该能力。考虑这个结构体声明: + +```move +struct Cup has copy, drop, store, key { item: T } +``` + + +It might be very helpful if `Cup` could hold any type, regardless of its abilities. The type system can *see* the type parameter, so it should be able to remove abilities from `Cup` if it *sees* a type parameter that would violate the guarantees for that ability. + +This behavior might sound a bit confusing at first, but it might be more understandable if we think about collection types. We could consider the builtin type `vector` to have the following type declaration: + +如果 `Cup` 可以容纳任何类型,可能会很有帮助,不管它的能力如何。类型系统可以 *看到* 类型参数,因此,如果它 *发现* 一个类型参数违反了对该能力的保证,它应该能够从 `Cup` 中删除能力。 + +这种行为一开始可能听起来有点令人困惑,但如果我们考虑一下集合类型,它可能会更容易理解。我们可以认为内置类型 `Vector` 具有以下类型声明: + +```move +vector has copy, drop, store; +``` + +We want `vector`s to work with any type. We don't want separate `vector` types for different abilities. So what are the rules we would want? Precisely the same that we would want with the field rules above. So, it would be safe to copy a `vector` value only if the inner elements can be copied. It would be safe to ignore a `vector` value only if the inner elements can be ignored/dropped. And, it would be safe to put a `vector` in global storage only if the inner elements can be in global storage. + +To have this extra expressiveness, a type might not have all the abilities it was declared with depending on the instantiation of that type; instead, the abilities a type will have depends on both its declaration **and** its type arguments. For any type, type parameters are pessimistically assumed to be used inside of the struct, so the abilities are only granted if the type parameters meet the requirements described above for fields. Taking `Cup` from above as an example: + +* `Cup` has the ability `copy` only if `T` has `copy`. +* It has `drop` only if `T` has `drop`. +* It has `store` only if `T` has `store`. +* It has `key` only if `T` has `store`. + +我们希望 `vector` 适用于任何类型。我们不希望针对不同的能力使用不同的 `vector` 类型。那么我们想要的规则是什么?与上面的字段规则完全相同。因此,仅当可以复制内部元素时,复制`vector` 值才是安全的。仅当可以忽略/丢弃内部元素时,忽略 `vector` 值才是安全的。而且,仅当内部元素可以在全局存储中时,将向量放入全局存储中才是安全的。 + +为了具有这种额外的表现力,一个类型可能不具备它声明的所有能力,具体取决于该类型的实例化;相反,一个类型的能力取决于它的声明 **和** 它的类型参数。对于任何类型,类型参数都被悲观地假定为在结构体内部使用,因此只有在类型参数满足上述字段要求时才授予这些能力。以上面的 `Cup` 为例: + +* `Cup` 拥有 `copy` 能力 仅当 `T` 拥有 `copy` 能力时。 +* `Cup` 拥有 `drop` 能力 仅当 `T` 拥有 `drop` 能力时。 +* `Cup` 拥有 `store` 能力 仅当 `T` 拥有 `store` 能力时。 +* `Cup` 拥有 `key` 能力 仅当 `T` 拥有 `store` 能力时。 + +Here are examples for this conditional system for each ability: + +以下是每个能力的条件系统的示例: + +### Example: conditional `copy` + +```move +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun example(c_x: Cup, c_s: Cup) { + // Valid, 'Cup' has 'copy' because 'u64' has 'copy' + let c_x2 = copy c_x; + // Valid, 'Cup' has 'copy' because 'S' has 'copy' + let c_s2 = copy c_s; +} + +fun invalid(c_account: Cup, c_n: Cup) { + // Invalid, 'Cup' does not have 'copy'. + // Even though 'Cup' was declared with copy, the instance does not have 'copy' + // because 'signer' does not have 'copy' + let c_account2 = copy c_account; + // Invalid, 'Cup' does not have 'copy' + // because 'NoAbilities' does not have 'copy' + let c_n2 = copy c_n; +} +``` + +### Example: conditional `drop` + +```move +struct NoAbilities {} +struct S has copy, drop { f: bool } +struct Cup has copy, drop, store { item: T } + +fun unused() { + Cup { item: true }; // Valid, 'Cup' has 'drop' + Cup { item: S { f: false }}; // Valid, 'Cup' has 'drop' +} + +fun left_in_local(c_account: Cup): u64 { + let c_b = Cup { item: true }; + let c_s = Cup { item: S { f: false }}; + // Valid return: 'c_account', 'c_b', and 'c_s' have values + // but 'Cup', 'Cup', and 'Cup' have 'drop' + 0 +} + +fun invalid_unused() { + // Invalid, Cannot ignore 'Cup' because it does not have 'drop'. + // Even though 'Cup' was declared with 'drop', the instance does not have 'drop' + // because 'NoAbilities' does not have 'drop' + Cup { item: NoAbilities {}}; +} + +fun invalid_left_in_local(): u64 { + let n = Cup { item: NoAbilities {}}; + // Invalid return: 'c_n' has a value + // and 'Cup' does not have 'drop' + 0 +} +``` + +### Example: conditional `store` + +```move +struct Cup has copy, drop, store { item: T } + +// 'MyInnerResource' is declared with 'store' so all fields need 'store' +struct MyInnerResource has store { + yes: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} + +// 'MyResource' is declared with 'key' so all fields need 'store' +struct MyResource has key { + yes: Cup, // Valid, 'Cup' has 'store' + inner: Cup, // Valid, 'Cup' has 'store' + // no: Cup, Invalid, 'Cup' does not have 'store' +} +``` + +### Example: conditional `key` + +```move +struct NoAbilities {} +struct MyResource has key { f: T } + +fun valid(account: &signer) acquires MyResource { + let addr = signer::address_of(account); + // Valid, 'MyResource' has 'key' + let has_resource = exists>(addr); + if (!has_resource) { + // Valid, 'MyResource' has 'key' + move_to(account, MyResource { f: 0 }) + }; + // Valid, 'MyResource' has 'key' + let r = borrow_global_mut>(addr) + r.f = r.f + 1; +} + +fun invalid(account: &signer) { + // Invalid, 'MyResource' does not have 'key' + let has_it = exists>(addr); + // Invalid, 'MyResource' does not have 'key' + let NoAbilities {} = move_from(addr); + // Invalid, 'MyResource' does not have 'key' + move_to(account, NoAbilities {}); + // Invalid, 'MyResource' does not have 'key' + borrow_global(addr); +} +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/abort-and-assert.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/abort-and-assert.md new file mode 100644 index 000000000..314940ee1 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/abort-and-assert.md @@ -0,0 +1,255 @@ +# 中止和断言 (Abort and Assert) + +[`return`](./functions.md) and `abort` are two control flow constructs that end execution, one for +the current function and one for the entire transaction. + +More information on [`return` can be found in the linked section](./functions.md) + +[`return`](./functions.md) 和 `abort` 是两种结束程序执行的控制流结构。前者针对当前函数,后者针对整个事务。 + + [`return`](./functions.md)的更多信息可以参考链接中的文章。 + +## `abort` 中止 + +`abort` is an expression that takes one argument: an **abort code** of type `u64`. For example: + +`abort` 表达式只接受一个参数: 类型为 `u64` 的**中止代码**。例如: + +```move +abort 42 +``` + +The `abort` expression halts execution the current function and reverts all changes made to global +state by the current transaction. There is no mechanism for "catching" or otherwise handling an `abort`. + +`abort` 表达式会中止执行当前函数并恢复当前事务对全局状态所做的所有更改。Move语言没有“捉捕”或者额外处理`abort`的机制。 + +Luckily, in Move transactions are all or nothing, meaning any changes to global storage are made all +at once only if the transaction succeeds. Because of this transactional commitment of changes, after +an abort there is no need to worry about backing out changes. While this approach is lacking in +flexibility, it is incredibly simple and predictable. + +幸运的是,在Move里事务的计算要么完全执行要么完全不执行。这意味着只有在事务成功时,任何对全局存储状态的改变才会被一并执行。 +由于这种对于所有更改的事务承诺,在 `abort` 之后我们不需要担心去回滚任何更改。尽管这种方法缺少灵活性,它还是非常简单和可预测的。 + + +Similar to [`return`](./functions.md), `abort` is useful for exiting control flow when some condition cannot be met. + +In this example, the function will pop two items off of the vector, but will abort early if the vector does not have two items + +与 [`return`](./functions.md)相似, 在一些条件无法被满足的时候,`abort` 可以被用于退出控制流(control flow)。 + +在以下示例中,目标函数会从vector里弹出两个元素,但是如果vector中并没有两个元素,函数会提前中止。 + +```move= +use std::vector; +fun pop_twice(v: &mut vector): (T, T) { + if (vector::length(v) < 2) abort 42; + + (vector::pop_back(v), vector::pop_back(v)) +} +``` + +This is even more useful deep inside a control-flow construct. For example, this function checks +that all numbers in the vector are less than the specified `bound`. And aborts otherwise + +这在控制流结构的深处甚至会更有用。例如,此函数检查vector中是否所有数字都小于指定的边界(`bound`)。否则函数中止: + +```move= +use std::vector; +fun check_vec(v: &vector, bound: u64) { + let i = 0; + let n = vector::length(v); + while (i < n) { + let cur = *vector::borrow(v, i); + if (cur > bound) abort 42; + i = i + 1; + } +} +``` + +### `assert` 断言 + +`assert` is a builtin, macro-like operation provided by the Move compiler. It takes two arguments, a condition of type `bool` and a code of type `u64` + +`assert` 是 Move 编译器提供的内置的类宏(macro-like)操作。它需要两个参数:一个 `bool` 类型的条件和一个 `u64` 类型的错误状态码(类似HTTP中的StatusCode: 404, 500等,译者注) + +```move +assert!(condition: bool, code: u64) +``` + +Since the operation is a macro, it must be invoked with the `!`. This is to convey that the +arguments to `assert` are call-by-expression. In other words, `assert` is not a normal function and +does not exist at the bytecode level. It is replaced inside the compiler with + +由于该操作是一个宏,因此必须使用 `!` 调用它。这是为了表达 `assert` 的参数属于表达式调用(call-by-expression)。换句话说,`assert` 不是一个正常的函数,并且在字节码(bytecode)级别不存在。它在编译器内部被替换为以下代码: + +```move +if (condition) () else abort code +``` + +`assert` is more commonly used than just `abort` by itself. The `abort` examples above can be rewritten using `assert` + +`assert` 比 `abort` 本身更常用。上面的 `abort` 示例可以使用 `assert` 重写 + +```move= +use std::vector; +fun pop_twice(v: &mut vector): (T, T) { + assert!(vector::length(v) >= 2, 42); // 现在使用'assert' + + (vector::pop_back(v), vector::pop_back(v)) +} +``` + +和 + +```move= +use std::vector; +fun check_vec(v: &vector, bound: u64) { + let i = 0; + let n = vector::length(v); + while (i < n) { + let cur = *vector::borrow(v, i); + assert!(cur <= bound, 42); // 现在使用 'assert' + i = i + 1; + } +} +``` + +Note that because the operation is replaced with this `if-else`, the argument for the `code` is not +always evaluated. For example: + +请注意,因为此操作被替换为 `if-else`,这段 `代码` 的参数不是总是被执行(evaluated)。例如: + +```move +assert!(true, 1 / 0) +``` + +Will not result in an arithmetic error, it is equivalent to + +不会导致算术错误,因为它相当于: + +```move +if (true) () else (1 / 0) +``` + +So the arithmetic expression is never evaluated! + +所以这个算术表达式永远不会被执行(evaluated)! + +### Abort codes in the Move VM (Move虚拟机中的中止代码) + +When using `abort`, it is important to understand how the `u64` code will be used by the VM. + +Normally, after successful execution, the Move VM produces a change-set for the changes made to +global storage (added/removed resources, updates to existing resources, etc). + +当使用 `abort` 时,理解虚拟机将如何使用 `u64` 代码是非常重要的。 + +通常,在成功执行后,Move 虚拟机会为对全局存储(添加/删除资源、更新现有资源等)所做的更改生成一个更改集。 + +If an `abort` is reached, the VM will instead indicate an error. Included in that error will be two +pieces of information: + +- The module that produced the abort (address and name) +- The abort code. + +For example + +如果执行到 `abort` 代码,虚拟机将指示错误。该错误中包含两块信息: + +- 发生中止的模块(地址和名称) +- 错误状态码。 + +例如 + +```move= +address 0x2 { + module example { + public fun aborts() { + abort 42 + } + } +} + +script { + fun always_aborts() { + 0x2::example::aborts() + } +} +``` + +If a transaction, such as the script `always_aborts` above, calls `0x2::example::aborts`, the VM +would produce an error that indicated the module `0x2::example` and the code `42`. + +This can be useful for having multiple aborts being grouped together inside a module. + +In this example, the module has two separate error codes used in multiple functions + +如果一个事务,例如上面的脚本 `always_aborts` 调用了 `0x2::example::aborts`,虚拟机将产生一个指示模块 `0x2::example` 和错误状态码 `42` 的错误。 + +这在一个模块内将多个中止功能组合起来会很有用。 + +在以下示例中,模块有两个单独的错误状态码,用于多个函数 + +```move= +address 0x42 { + module example { + + use std::vector; + + const EMPTY_VECTOR: u64 = 0; + const INDEX_OUT_OF_BOUNDS: u64 = 1; + + // 移动 i 到 j, 移动 j 到 k, 移动 k 到 i + public fun rotate_three(v: &mut vector, i: u64, j: u64, k: u64) { + let n = vector::length(v); + assert!(n > 0, EMPTY_VECTOR); + assert!(i < n, INDEX_OUT_OF_BOUNDS); + assert!(j < n, INDEX_OUT_OF_BOUNDS); + assert!(k < n, INDEX_OUT_OF_BOUNDS); + + vector::swap(v, i, k); + vector::swap(v, j, k); + } + + public fun remove_twice(v: &mut vector, i: u64, j: u64): (T, T) { + let n = vector::length(v); + assert!(n > 0, EMPTY_VECTOR); + assert!(i < n, INDEX_OUT_OF_BOUNDS); + assert!(j < n, INDEX_OUT_OF_BOUNDS); + assert!(i > j, INDEX_OUT_OF_BOUNDS); + + (vector::remove(v, i), vector::remove(v, j)) + } + } +} +``` + +## The type of `abort` (`abort` 的类型) + +The `abort i` expression can have any type! This is because both constructs break from the normal +control flow, so they never need to evaluate to the value of that type. + +The following are not useful, but they will type check + +`abort i` 表达式可以有任何类型!这是因为这两种构造都打破了正常控制流,因此他们永远不需要计算该类型的值。 + +以下的示例不是特别有用,但它们会做类型检查 + +```move +let y: address = abort 0; +``` + +This behavior can be helpful in situations where you have a branching instruction that produces a +value on some branches, but not all. For example: + +在您有一个分支指令,并且这个指令会产生某些分支(不是全部)的值的时候,这种行为会非常有用。例如: + +```move +let b = + if (x == 0) false + else if (x == 1) true + else abort 42; +// ^^^^^^^^ `abort 42` 的类型是 `bool` +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/address.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/address.md new file mode 100644 index 000000000..1a5edc9d9 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/address.md @@ -0,0 +1,58 @@ +# 地址 + +`地址(address)`是 Move 中的内置类型,用于表示全局存储中的的位置(有时称为账户)。`地址(address)` 值是一个 128 位(16 字节)标识符。在一个给定的地址,可以存储两样东西:[模块(Module)](./modules-and-scripts.md)和[资源(Resources)](./structs-and-resources.md)。 + +虽然`地址(address)`在底层是一个 128 位整数,但 Move 语言有意让其不透明 —— 它们不能从整数创建,不支持算术运算,也不能修改。即使可能有一些有趣的程序会使用这种特性(例如,C 中的指针算法实现了类似壁龛(niche)的功能),但 Move 语言不允许这种动态行为,因为它从头开始就被设计为支持静态验证。*(壁龛指安装在墙壁上的小格子或在墙身上留出的作为贮藏设施的空间,最早在宗教上是指排放佛像的小空间,现在多用在家庭装修上,因其不占建筑面积,使用比较方便,深受大家喜爱,Joe 注)* + +你可以通过运行时地址值(`address` 类型的值)来访问该地址处的资源。但*无法*在运行时通过地址值访问模块。 + +## 地址及其语法 + +地址有两种形式:*命名的*或*数值的*。命名地址的语法遵循 Move 命名标识符的规则。数值地址的语法不受十六进制编码值的限制,任何有效的 [`u128` 数值](./integers.md)都可以用作地址值。例如,`42`,`0xCFAE` 和 `2021` 都是合法有效的数值地址字面量(literal)。 + +为了区分何时在表达式上下文中使用地址,使用地址时的语法根据使用地址的上下文而有所不同: + +* 当地址被用作表达式时,地址必须以 `@` 字符为前缀,例如:[`@`](./integers.md) 或 `@`。 +* 在表达式上下文之外,地址可以不带前缀字符 `@`。例如:[``](./integers.md) 或 ``。 + +通常,可以将 `@` 视为将地址从命名空间项变为表达式项的运算符。 + +## 命名地址 + +命名地址是一项特性,它允许在使用地址的任何地方使用标识符代替数值,而不仅仅是在值级别。命名地址被声明并绑定为 Move 包中的顶级元素(模块和脚本之外)或作为参数传递给 Move 编译器。 + +命名地址仅存在于源语言级别,并将在字节码级别完全替代它们的值。因此,模块和模块成员*必须*通过模块的命名地址而不是编译期间分配给命名地址的数值来访问,例如:`use my_addr::foo` *不等于* `use 0x2::foo`,即使 Move 程序编译时将 `my_addr` 设置成 `0x2`。这个区别在[模块和脚本](./modules-and-scripts.md)一节中有更详细的讨论。 + +### 例子 + +```move +let a1: address = @0x1; // 0x00000000000000000000000000000001 的缩写 +let a2: address = @0x42; // 0x00000000000000000000000000000042 的缩写 +let a3: address = @0xDEADBEEF; // 0x000000000000000000000000DEADBEEF 的缩写 +let a4: address = @0x0000000000000000000000000000000A; +let a5: address = @std; // 将命名地址 `std` 的值赋给 `a5` +let a6: address = @66; +let a7: address = @0x42; + +module 66::some_module { // 不在表达式上下文中,所以不需要 @ + use 0x1::other_module; // 不在表达式上下文中,所以不需要 @ + use std::vector; // 使用其他模块时,可以使用命名地址作为命名空间项 + ... +} + +module std::other_module { // 可以使用命名地址作为命名空间项来声明模块 + ... +} +``` + +## 全局存储操作 + +`address` 值主要用来与全局存储操作进行交互。 + +`address` 值与 `exists`、`borrow_global`、`borrow_global_mut` 和 `move_from` [操作(operation)](./global-storage-operators.md)一起使用。 + +唯一*不使用* `address` 的全局存储操作是 `move_to`,它使用了 [`signer`](./signer.md)。 + +## 所有权 + +与 Move 语言内置的其他标量值一样,`address` 值是隐式可复制的,这意味着它们可以在没有显式指令(例如 [`copy`](./variables.md#移动和复制))的情况下复制。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/bool.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/bool.md new file mode 100644 index 000000000..d49844ddb --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/bool.md @@ -0,0 +1,49 @@ +# 布尔类型 (Bool) + +`bool`is Move's primitive type for boolean `true` and `false`values. + +`bool` 是 Move 布尔基本类型,有 `true` 和 `false` 两个值。 + +## 字面量 (Literals) + +Literals for `bool` are either `true` or `false` . + +布尔类型字面值只能是 `true` 或者 `false`中的一个 。 + +## 操作 (Operations) + +### 逻辑运算 (Logical) + +`bool`supports three logical operations: + +| Syntax | Description | Equivalent Expression | +| ------------------------- | ---------------------------- | ------------------------------------------------------------------- | +| `&&` | short-circuiting logical and | `p && q` is equivalent to `if (p) q else false` | +| || | short-circuiting logical or | p || q is equivalent to `if (p) true else q` | +| `!` | logical negation | `!p` is equivalent to `if (p) false else true` | + + +`bool` 支持三种逻辑运算: + +| 句法 | 描述 | Equivalent Expression | +| ------ | ---------------------------- | ----------------------------------------------- | +| `&&` | 短路逻辑与(short-circuiting logical and) | `p && q` 等价于 `if (p) q else false` | +| || | 短路逻辑或(short-circuiting logical or) | `p || q` 等价于 `if (p) true else q` | +| `!` | 逻辑非(logical negation) | `!p` 等价于 `if (p) false else true` | + + +### 控制流 (Control Flow) + +`bool`values are used in several of Move's control-flow constructs: + +布尔值用于 Move 的多个控制流结构中: + +- [`if (bool) { ... }`](./conditionals.html) +- [`while (bool) { .. }`](/loops.html) +- [`assert!(bool, u64)`](./abort-and-assert.html) + +## 所有权 (Ownership) + +As with the other scalar values built-in to the language, boolean values are implicitly copyable, meaning they can be copied without an explicit instruction such as `[copy]().` + +与语言内置的其他标量值一样,布尔值是隐式可复制的,这意味着它们可以在没有明确指令如[`copy`](./variables.md#move-and-copy)的情况下复制。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/coding-conventions.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/coding-conventions.md new file mode 100644 index 000000000..0ea7920b8 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/coding-conventions.md @@ -0,0 +1,76 @@ +# Move 编码约定 + +本节列出了 Move 团队认为有用的一些基本的 Move 编码约定。这些只是建议,如果你喜欢其他格式指南和约定,你可以随时使用它们。 + +## 命名 + +- **模块名称**:应该使用小写的蛇形命名法,例如:`fixed_point32`、`vector`。 +- **类型名称**:如果不是原生数据类型,则应使用驼峰命名法,例如:`Coin`、`RoleId`。 +- **函数名称**:应该使用小写的蛇形命名法,例如:`destroy_empty`。 +- **常量名称**:应该使用大写的蛇形命名法,例如:`REQUIRES_CAPABILITY`。 +- 泛型类型应该具备描述性,当然在适当的情况下也可以是反描述性的,例如:Vector 泛型类型的参数可以是 `T` 或 `Element`。大多数情况下,模块中的“主”类型命名应该与模块名相同,例如:`option::Option`,`fixed_point32::FixedPoint32`。 +- **模块文件名称**:应该与模块名相同,例如:`Option.move`。 +- **脚本文件名称**:应该使用小写的蛇形命名法,并且应该与脚本中的“主”函数名匹配。 +- **混合文件名称**:如果文件包含多个模块和/或脚本,文件命名应该使用小写的蛇形命名法,并且不需要与内部的任何特定模块/脚本名匹配。 + +## 导入 + +- 所有模块的 `use` 语句都应该位于模块的顶部。 +- 函数应该从声明它们的模块中完全限定地导入和使用, 而不是在顶部导入。 +- 类型应该在顶部导入。如果存在名称冲突,应使用 `as` 在本地适当地重命名类型。 + +例如,如果有一个模块: + +```move +module 0x1::foo { + struct Foo { } + const CONST_FOO: u64 = 0; + public fun do_foo(): Foo { Foo{} } + ... +} +``` + +此时将被导入并使用: + +```move +module 0x1::bar { + use 0x1::foo::{Self, Foo}; + + public fun do_bar(x: u64): Foo { + if (x == 10) { + foo::do_foo() + } else { + abort 0 + } + } + ... +} +``` + +并且,如果在导入两个模块时存在本地名称冲突: + +```move +module other_foo { + struct Foo {} + ... +} + +module 0x1::importer { + use 0x1::other_foo::Foo as OtherFoo; + use 0x1::foo::Foo; + ... +} +``` + +## 注释 + +- 每个模块、结构体和公共函数声明都应该有对应的注释。 +- Move 有文档注释 `///`,常规单行注释 `//`,块注释 `/* */`,和块文档注释 `/** */`。 + +## 格式化 + +Move 团队计划编写一个自动格式化程序来执行格式化约定。然而,在此期间: + +- 除 `script` 和 `address` 块外,其他的内容应使用四个空格的缩进。 +- 每行代码,如果超过 100 个字符,应该换行。 +- 结构体和常量应该在模块中的所有函数之前声明。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/conditionals.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/conditionals.md new file mode 100644 index 000000000..0edbb8c42 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/conditionals.md @@ -0,0 +1,78 @@ +# 条件语句 (Conditionals) + +An `if` expression specifies that some code should only be evaluated if a certain condition is true. For example: + +`if` 语句可以用来指定一块代码块,但只在判断条件(condition)为true时才会被执行。例如: + +```move +if (x > 5) x = x - 5 +``` + +The condition must be an expression of type `bool`. + +An `if` expression can optionally include an `else` clause to specify another expression to evaluate when the condition is false. + +条件语句(condition)必须是 `bool` 类型的表达式。 + +`if` 语句可选包含 `else` 子句,以指定当条件(condition)为 false 时要执行的另一个代码块。 + +```move +if (y <= 10) y = y + 1 else y = 10 +``` + +Either the "true" branch or the "false" branch will be evaluated, but not both. Either branch can be a single expression or an expression block. + +The conditional expressions may produce values so that the `if` expression has a result. + +无论是"true"分支还是"false"分支都会被执行,但不会同时执行.其中任何一个分支都可以是单行代码或代码块。条件表达式会产生值,所以 `if` 表达式会有一个结果。 + +```move +let z = if (x < 100) x else 100; +``` + +The expressions in the true and false branches must have compatible types. For example: + +true 和 false 分支的表达式类型必须是一致的,例如: + +```move= +// x和y必须是u64整型 +// x and y must be u64 integers +let maximum: u64 = if (x > y) x else y; + +// 错误!分支的类型不一致 +// (ERROR! branches different types) +let z = if (maximum < 10) 10u8 else 100u64; + +// 错误!分支的类型不一致,false-branch默认是()不是u64 +// ERROR! branches different types, as default false-branch is () not u64 +if (maximum >= 10) maximum; +``` + +If the `else` clause is not specified, the false branch defaults to the unit value. The following are equivalent: + +如果`else`子句未定义,false分支默认为 unit 。下面的例子是相等价的: + +```move +if (condition) true_branch // implied default: else () +if (condition) true_branch else () +``` + +Commonly, [`if` expressions](./conditionals.md) are used in conjunction with expression blocks. + +一般来说, [`if` 表达式](./conditionals.md)与多个表达式块结合使用. + +```move +let maximum = if (x > y) x else y; +if (maximum < 10) { + x = x + 10; + y = y + 10; +} else if (x >= 10 && y >= 10) { + x = x - 10; + y = y - 10; +} +``` + +## 条件语句的语法 (Grammar for Conditionals) + +> *if-expression* → **if (** *expression* **)** *expression* *else-clause**opt* +> *else-clause* → **else** *expression* diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/constants.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/constants.md new file mode 100644 index 000000000..380322e8f --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/constants.md @@ -0,0 +1,136 @@ +# 常量 (Constants) + +Constants are a way of giving a name to shared, static values inside of a `module` or `script`. + +The constant's must be known at compilation. The constant's value is stored in the compiled module +or script. And each time the constant is used, a new copy of that value is made. + +常量是一种对 `module` 或 `script` 内的共享静态值进行命名的方法(类似变量,但值不变,译者注)。 + +常量必须在编译时知道。常量的值存储在编译模块或脚本中。每次使用该常量时,都会生成该值的新副本。 + +## 声明 (Declaration) + +Constant declarations begin with the `const` keyword, followed by a name, a type, and a value. They +can exist in either a script or module + +常量声明以 `const` 关键字开头,后跟名称、类型和值。他们可以存在于脚本或模块中 + +```text +const : = ; +``` + +例如 + +```move= +script { + + const MY_ERROR_CODE: u64 = 0; + + fun main(input: u64) { + assert!(input > 0, MY_ERROR_CODE); + } + +} + +address 0x42 { + module example { + + const MY_ADDRESS: address = @0x42; + + public fun permissioned(s: &signer) { + assert!(std::signer::address_of(s) == MY_ADDRESS, 0); + } + + } +} +``` + +## 命名 (Naming) + +Constants must start with a capital letter `A` to `Z`. After the first letter, constant names can +contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, or digits `0` to `9`. + +常量必须以大写字母 `A` 到 `Z` 开头。在第一个字母之后,常量名可以包含下划线 `_`、字母 `a` 到 `z`、字母 `A` 到 `Z` 或数字 `0` 到 `9`。 + +```move +const FLAG: bool = false; +const MY_ERROR_CODE: u64 = 0; +const ADDRESS_42: address = @0x42; +``` + +Even though you can use letters `a` to `z` in a constant. The +[general style guidelines](./coding-conventions.md) are to use just uppercase letters `A` to `Z`, +with underscores `_` between each word. + +虽然你可以在常量中使用字母 `a` 到 `z`。但[通用风格指南](./coding-conventions.md) 只使用大写字母 `A` 到 `Z`,每个单词之间有下划线`_`。 + +This naming restriction of starting with `A` to `Z` is in place to give room for future language features. It may or may not be removed later. + +这种以 `A` 到 `Z` 开头的命名限制是为了给未来的语言特性留出空间。此限制未来可能会保留或删除。 + +## 可见性 (Visibility) + +`public` constants are not currently supported. `const` values can be used only in the declaring +module. + +当前不支持 `public` 常量。 `const` 值只能在声明的模块中使用。 + +## 有效表达式 (Valid Expressions) + +Currently, constants are limited to the primitive types `bool`, `u8`, `u64`, `u128`, `address`, and +`vector`. Future support for other `vector` values (besides the "string"-style literals) will come later. + +目前,常量仅限于原始类型 `bool`、`u8`、`u64`、`u128`、`address` 和`vector`。其他 `vector` 值(除了“string”风格的字面量)将在不远的将来获得支持。 + +### 值 (Values) + +Commonly, `const`s are assigned a simple value, or literal, of their type. For example + +通常,`const` (常量)会被分配一个对应类型的简单值或字面量。例如 + +```move +const MY_BOOL: bool = false; +const MY_ADDRESS: address = @0x70DD; +const BYTES: vector = b"hello world"; +const HEX_BYTES: vector = x"DEADBEEF"; +``` + +### 复杂表达式 (Complex Expressions) + + +In addition to literals, constants can include more complex expressions, as long as the compiler is +able to reduce the expression to a value at compile time. + +Currently, equality operations, all boolean operations, all bitwise operations, and all arithmetic +operations can be used. + +除了字面量,常量还可以包含更复杂的表达式,只要编译器能够在编译时将表达式归纳(reduce)为一个值。 + +目前,相等运算、所有布尔运算、所有按位运算和所有算术运算可以使用。 + +```move +const RULE: bool = true && false; +const CAP: u64 = 10 * 100 + 1; +const SHIFTY: u8 = { + (1 << 1) * (1 << 2) * (1 << 3) * (1 << 4) +}; +const HALF_MAX: u128 = 340282366920938463463374607431768211455 / 2; +const EQUAL: bool = 1 == 1; +``` + +If the operation would result in a runtime exception, the compiler will give an error that it is +unable to generate the constant's value + +如果操作会导致运行时异常,编译器会给出无法生成常量值的错误。 + +```move +const DIV_BY_ZERO: u64 = 1 / 0; // error! +const SHIFT_BY_A_LOT: u64 = 1 << 100; // error! +const NEGATIVE_U64: u64 = 0 - 1; // error! +``` + +Note that constants cannot currently refer to other constants. This feature, along with support for +other expressions, will be added in the future. + +请注意,常量当前不能引用其他常量。此功能会在将来和支持其他表达方式一起被补充。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/creating-coins.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/creating-coins.md new file mode 100644 index 000000000..1f06df9a0 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/creating-coins.md @@ -0,0 +1,7 @@ +# Move Tutorial + +Please refer to the [Move Tutorial](https://github.com/move-language/move/tree/main/language/documentation/tutorial). + +# Move 教程 + +请参阅 [Move 教程](https://github.com/move-language/move/tree/main/language/documentation/tutorial)。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/equality.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/equality.md new file mode 100644 index 000000000..2abe89623 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/equality.md @@ -0,0 +1,192 @@ + +# 等式 (Equality) + +Move supports two equality operations `==` and `!=` + +Move 支持两种等式操作: `==` 和 `!=` + +## 操作 (Operations) + +| Syntax | Operation | Description | +| ------ | --------- | --------------------------------------------------------------------------- | +| `==` | equal | Returns `true` if the two operands have the same value, `false` otherwise | +| `!=` | not equal | Returns `true` if the two operands have different values, `false` otherwise | + +| 语法 | 操作 | 描述 | +| ------ | --------- | --------------------------------------------------------------------------- | +| `==` | 相等 | 如果两个操作数(operands)值相同,返回 `true` , 否则返回 `false` | +| `!=` | 不相等 | 如果两个操作数(operands)值不相同,返回 `true` , 否则返回 `false` | + +### 类型校验 (Typing) + +Both the equal (`==`) and not-equal (`!=`) operations only work if both operands are the same type. + +只有当左右两个操作数类型相同,相等操作 (`==`) 与不等操作 (`!=`) 才能正常使用。 + +```move +0 == 0; // `true` +1u128 == 2u128; // `false` +b"hello" != x"00"; // `true` +``` + +Equality and non-equality also work over user defined types! + +等式与不等式也可以在用户自定义的类型下使用! + +```move= +address 0x42 { + module example { + struct S has copy, drop { f: u64, s: vector } + + fun always_true(): bool { + let s = S { f: 0, s: b"" }; + // 括号不是必需的,但为了清楚起见在此示例中添加了括号 + (copy s) == s + } + + fun always_false(): bool { + let s = S { f: 0, s: b"" }; + // 括号不是必需的,但为了清楚起见在此示例中添加了括号 + (copy s) != s + } + } +} +``` + +If the operands have different types, there is a type checking error. + +如果两边操作数的类型不同,则会出现类型检测错误。 + +```move +1u8 == 1u128; // 错误! +// ^^^^^ 期望此变量的类型是 'u8' +b"" != 0; // 错误! +// ^ 期望此变量的类型是 'vector' +``` + +### 引用变量的类型校验 (Typing with references) + +When comparing [references](./references.md), the type of the reference (immutable or mutable) does +not matter. This means that you can compare an immutable `&` reference with a mutable one `&mut` of +the same underlying type. + +当比较[引用变量](./references.md)时,引用的类别(不可变更的或可变更的(immutable or mutable))无关紧要。这意味着我们可以拿一个不可变更的 `&` 引用变量和另一个有相同相关类型的可变更的 `&mut ` 引用变量进行比较。 + +```move +let i = &0; +let m = &mut 1; + +i == m; // `false` +m == i; // `false` +m == m; // `true` +i == i; // `true` +``` + +The above is equivalent to applying an explicit freeze to each mutable reference where needed + +在需要时,对每个可变引用使用显式冻结(explicit freeze)的结果与上述情况一致。 + +```move +let i = &0; +let m = &mut 1; + +i == freeze(m); // `false` +freeze(m) == i; // `false` +m == m; // `true` +i == i; // `true` +``` +But again, the underlying type must be the same type + +但同样的,我们需要两边操作数的类型一致 + +```move +let i = &0; +let s = &b""; + +i == s; // 错误! +// ^ 期望此变量的类型是 '&u64' +``` + +## 限制 (Restrictions) + +Both `==` and `!=` consume the value when comparing them. As a result, the type system enforces that +the type must have [`drop`](./abilities.md). Recall that without the [`drop` ability](./abilities.md), +ownership must be transferred by the end of the function, and such values can only be explicitly destroyed +within their declaring module. If these were used directly with either equality `==` or non-equality `!=`, +the value would be destroyed which would break [`drop` ability](./abilities.md) safety guarantees! + +`==` 和 `!=` 会在比较不同变量的时候消耗 (consume)它们所包含的值,所以 Move 的类型系统会强制要求这些类型含有[`drop` 能力](./abilities.md)。回想一下,变量在没有[`drop` 能力](./abilities.md)时,所有权必须在函数结束前进行转移,而且这些值只能在其声明模块中被明确销毁(explicitly destroyed)。如果它们被直接使用于等式 `==` 或不等式 `!=` ,其值会被销毁并且这会打破[`drop` 能力](./abilities.md)的安全保证! + +```move= +address 0x42 { + module example { + struct Coin has store { value: u64 } + fun invalid(c1: Coin, c2: Coin) { + c1 == c2 // 错误! + // ^^ ^^ 这些资源将会被销毁! + } + } +} +``` + + +But, a programmer can _always_ borrow the value first instead of directly comparing the value, and +reference types have the [`drop` ability](./abilities.md). For example + +然而, 程序员 _总是_ 可以优先借用变量的值,而不直接比较它们的值。这样一来,引用变量的类型将会拥有[`drop` 能力](./abilities.md)。例如: + +```move= +address 0x42 { + module example { + struct Coin as store { value: u64 } + fun swap_if_equal(c1: Coin, c2: Coin): (Coin, Coin) { + let are_equal = &c1 == &c2; // 合规范的 + if (are_equal) (c2, c1) else (c1, c2) + } + } +} +``` + +## 避免额外的复制 (Avoid Extra Copies) + +While a programmer _can_ compare any value whose type has [`drop`](./abilities.md), a programmer +should often compare by reference to avoid expensive copies. + +当程序员 _可以_ 比较其类型含有[`drop` 能力](./abilities.md)的任意值时,他们应该尽可能多地使用引用变量来比较,以此来避免昂贵的复制。 + +```move= +let v1: vector = function_that_returns_vector(); +let v2: vector = function_that_returns_vector(); +assert!(copy v1 == copy v2, 42); +// ^^^^ ^^^^ +use_two_vectors(v1, v2); + +let s1: Foo = function_that_returns_large_struct(); +let s2: Foo = function_that_returns_large_struct(); +assert!(copy s1 == copy s2, 42); +// ^^^^ ^^^^ +use_two_foos(s1, s2); +``` + +This code is perfectly acceptable (assuming `Foo` has [`drop`](./abilities.md)), just not efficient. +The highlighted copies can be removed and replaced with borrows + +以上代码是完全可以接受的(假设`Foo`具备[`drop`](./abilities.md)能力),但它不是最有效的写法。突出显示的副本可以删除并替换为借用。 + +```move= +let v1: vector = function_that_returns_vector(); +let v2: vector = function_that_returns_vector(); +assert!(&v1 == &v2, 42); +// ^ ^ +use_two_vectors(v1, v2); + +let s1: Foo = function_that_returns_large_struct(); +let s2: Foo = function_that_returns_large_struct(); +assert!(&s1 == &s2, 42); +// ^ ^ +use_two_foos(s1, s2); +``` + +The efficiency of the `==` itself remains the same, but the `copy`s are removed and thus the program is more efficient. + +`==` 本身的效率还是和之前一样,但是 `copy` 操作被移除后整个程序会比之前更有效率。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/friends.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/friends.md new file mode 100644 index 000000000..238dce84f --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/friends.md @@ -0,0 +1,154 @@ +# 友元函数(Friends) + +The `friend` syntax is used to declare modules that are trusted by the current module. +A trusted module is allowed to call any function defined in the current module that have the `public(friend)` visibility. +For details on function visibilities, please refer to the *Visibility* section in [Functions](./functions.md). + +友元语法用于声明当前模块信任的其它模块。受信任的模块可以调用当前模块中定义的任何具有`公开(友元)`可见性的函数。有关函数可见性的详细信息,请参阅[函数](./functions.md)中的可见性部分。 + +## 友元声明(Friend declaration) + +A module can declare other modules as friends via friend declaration statements, in the format of + +一个模块可以通过友元声明语句将其他模块声明为友元,格式为: + +- `friend ` — friend declaration using fully qualified module name like the example below, or +- `friend —` 使用完全合格的模块名称的友元声明,如下例所示,或 + + ``` + address 0x42 { + module a { + friend 0x42::b; + } + } + ``` + +- `friend ` — friend declaration using a module name alias, where the module alias is introduced via the `use` statement. +- `friend —` 使用模块名称别名的友元声明,其中模块别名是通过use语句引入的。 + + ```move + address 0x42 { + module a { + use 0x42::b; + friend b; + } + } + ``` + +A module may have multiple friend declarations, and the union of all the friend modules forms the friend list. +In the example below, both `0x42::B` and `0x42::C` are considered as friends of `0x42::A`. + +一个模块可能有多个友元声明,所有好友模块的并集形成友元列表。在下面的示例中`,0x42::B`和`0x42::C`都被视为 的友元函数`0x42::A`。 + + ```move + address 0x42 { + module a { + friend 0x42::b; + friend 0x42::c; + } + } + ``` + +Unlike `use` statements, `friend` can only be declared in the module scope and not in the expression block scope. +`friend` declarations may be located anywhere a top-level construct (e.g., `use`, `function`, `struct`, etc.) is allowed. +However, for readability, it is advised to place friend declarations near the beginning of the module definition. + +与`use`语句不同,`friend`只能在模块作用域内声明,而不能在表达式块的作用域内声明。`friend`声明可以位于允许顶层构造的任何位置(例如, `use`, `function,struct`等)是被允许的。但是,为了可读性,建议将友元声明放在模块定义的开头附近。 + +Note that the concept of friendship does not apply to Move scripts: +- A Move script cannot declare `friend` modules as doing so is considered meaningless: there is no mechanism to call the function defined in a script. +- A Move module cannot declare `friend` scripts as well because scripts are ephemeral code snippets that are never published to global storage. + +请注意,友元关系(friendship)的概念不适用于 Move 脚本: +- `Move` 脚本不能声明`friend`模块,因为这样做被认为是无意义的:没有机制可以调用脚本中定义的函数。 +- `Move` 模块也不能声明`friend`脚本,因为脚本是永远不会发布到全局存储的临时代码片段。 + +### 友元声明规则(Friend declaration rules) +Friend declarations are subject to the following rules: +友元声明须遵守以下规则: + +- A module cannot declare itself as a friend +- 一个模块不能将自己声明为友元。 + + ```move= + address 0x42 { + module m { friend Self; // 错误! } + // ^^^^ 不能将自己声明为友元 + } + + address 0x43 { + module m { friend 0x43::M; // 错误! } + // ^^^^^^^ 不能将自己声明为友元 + } + ``` + +- Friend modules must be known by the compiler +- 编译器必须知道友元模块 + + ```move= + address 0x42 { + module m { friend 0x42::nonexistent; // 错误! } + // ^^^^^^^^^^^^^^^^^ 未绑定的模块 '0x42::nonexistent' + } + ``` + + - Friend modules must be within the same account address. (Note: this is not a technical requirement but rather a policy decision which *may* be relaxed later.) + + - 友元模块必须在同一个账号地址内。(注:这不是技术要求,而是以后可能放宽的决策。) + + ```move + address 0x42 { + module m {} + } + + address 0x43 { + module n { friend 0x42::m; // 错误! } + // ^^^^^^^ 不能声明当前地址外的模块作为友元 + } + ``` + +- 友元关系不能创建循环模块依赖关系(Friends relationships cannot create cyclic module dependencies) + +Cycles are not allowed in the friend relationships, e.g., the relation `0x2::a` friends `0x2::b` friends `0x2::c` friends `0x2::a` is not allowed. +More generally, declaring a friend module adds a dependency upon the current module to the friend module (because the purpose is for the friend to call functions in the current module). +If that friend module is already used, either directly or transitively, a cycle of dependencies would be created. + +友元关系中不允许循环,例如 `0x2::a` 友元 `0x2::b` 友元 `0x2::c` 友元`0x2::a`是不允许的。更普遍地,声明一个友元模块会将对当前模块的依赖添加到友元模块(因为目的是让友元调用当前模块中的函数)。如果该友元模块已被直接或传递地使用,则将形成一个依赖循环。 + + ```move + address 0x2 { + module a { + use 0x2::c; + friend 0x2::b; + + public fun a() { + c::c() + } + } + + module b { + friend 0x2::c; // 错误! + // ^^^^^^ 这个友元关系形成了一个依赖循环: '0x2::a' 使用了 '0x2::c' 但'0x2::b' 同时是 '0x2::a'和'0x2::b' 的友元 + } + + module c { + public fun c() {} + } + } +``` + +- The friend list for a module cannot contain duplicates. +- 模块的友元列表不能包含重复项。 + + ```move= + address 0x42 { + module a {} + + module m { + use 0x42::a as aliased_a; + friend 0x42::A; + friend aliased_a; // 错误! + // ^^^^^^^^^ 重复的友元声明 '0x42::a'. 模块内的友元声明必须是唯一的 + } + } + ``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/functions.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/functions.md new file mode 100644 index 000000000..e0fb8d2a0 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/functions.md @@ -0,0 +1,607 @@ +# 函数 (Functions) + +Function syntax in Move is shared between module functions and script functions. Functions inside of modules are reusable, whereas script functions are only used once to invoke a transaction. + +Move中的函数语法在模块函数和脚本函数之间是一致的。模块内部的函数可重复使用,而脚本的函数只能被使用一次用来调用事务。 + +# 声明 (Declaration) + +Functions are declared with the `fun` keyword followed by the function name, type parameters, parameters, a return type, acquires annotations, and finally the function body. + +函数使用 `fun` 关键字声明,后跟函数名称、类型参数、参数、返回类型、获取标注(annotation),最后是函数体。 + +```text +fun <[type_parameters: constraint],*>([identifier: type],*): +``` + +例如 + +```move +fun foo(x: u64, y: T1, z: T2): (T2, T1, u64) { (z, y, x) } +``` + +### 可见性 (Visibility) + +Module functions, by default, can only be called within the same module. These internal (sometimes called private) functions cannot be called from other modules or from scripts. + +默认情况下,模块函数只能在同一个模块内调用。这些内部(有时称为私有)函数不能从其他模块或脚本中调用。 + +```move= +address 0x42 { + module m { + fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid + } + + module other { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! + // ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } + } +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } +} +``` + +To allow access from other modules or from scripts, the function must be declared `public` or `public(friend)`. + +要允许从其他模块或脚本访问,该函数必须声明为 `public` 或 `public(friend)`。 + +#### `public` 可见性 (`public` visibility) + +A `public` function can be called by *any* function defined in *any* module or script. As shown in the following example, a `public` function can be called by: +- other functions defined in the same module, +- functions defined in another module, or +- the function defined in a script. + +`public` 函数可以被任何模块或脚本中定义的任何函数调用。如以下示例所示,可以通过以下方式调用 `public` 函数: + +- 在同一模块中定义的其他函数 +- 在另一个模块中定义的函数 +- 在脚本中定义的函数 + +```move= +address 0x42 { + module m { + public fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid + } + + module other { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid + } + } +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid + } +} +``` + +#### `public(friend)` 可见性 (`public(friend)` visibility) + +The `public(friend)` visibility modifier is a more restricted form of the `public` modifier to give more control about where a function can be used. A `public(friend)` function can be called by: +- other functions defined in the same module, or +- functions defined in modules which are explicitly specified in the **friend list** (see [Friends](./friends.md) on how to specify the friend list). + +Note that since we cannot declare a script to be a friend of a module, the functions defined in scripts can never call a `public(friend)` function. + +`public(friend)` 可见性修饰符是一种比 `public` 修饰符限制更严格的形式,可以更好地控制函数的使用位置。 `public(friend)` 函数可以通过以下方式调用: + +- 在同一模块中定义的其他函数,或者在 **friend list** 中明确指定的模块中定义的函数(请参阅 [Friends](./friends.md) 了解如何指定友元(friends)列表)。 + +请注意,由于我们不能将脚本声明为模块的友元关系,因此脚本中定义的函数永远不能调用 `public(friend)` 函数。 + +```move= +address 0x42 { + module m { + friend 0x42::n; // friend declaration + public(friend) fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid + } + + module n { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid + } + } + + module other { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! + // ^^^^^^^^^^^^ 'foo' can only be called from a 'friend' of module '0x42::m' + } + } +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' can only be called from a 'friend' of module '0x42::m' + } +} +``` + +### `entry` 修饰符 (`entry` modifier) + +The `entry` modifier is designed to allow module functions to be safely and directly invoked much like scripts. This allows module writers to specify which functions can be to begin execution. The module writer then knows that any non-`entry` function will be called from a Move program already in execution. + +Essentially, `entry` functions are the "main" functions of a module, and they specify where Move programs start executing. + +Note though, an `entry` function _can_ still be called by other Move functions. So while they _can_ serve as the start of a Move program, they aren't restricted to that case. + +`entry` 修饰符旨在允许像脚本一样安全直接地调用模块函数。这允许模块编写者指定哪些函数可以成为开始执行的入口。这样模块编写者就知道任何非`entry`函数都是从已经在执行的 Move 程序中被调用的。 + +本质上,`entry` 函数是模块的“main”函数,它们指定 Move 程序开始执行的位置。 + +但请注意,`entry` 函数仍可被其他 Move 函数调用。因此,虽然它们 _可以_ 作为 Move 程序的入口,但它们并不局限于这种用法。 + +例如: + +```move= +address 0x42 { + module m { + public entry fun foo(): u64 { 0 } + fun calls_foo(): u64 { foo() } // valid! + } + + module n { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid! + } + } + + module other { + public entry fun calls_m_foo(): u64 { + 0x42::m::foo() // valid! + } + } +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // valid! + } +} +``` + +Even internal functions can be marked as `entry`! This lets you guarantee that the function is called only at the beginning of execution (assuming you do not call it elsewhere in your module) + +甚至内部函数也可以标记为 `entry`!这使你可以保证仅在开始执行时调用该函数(假如你没有在模块中的其他地方调用它) + +```move= +address 0x42 { + module m { + entry fun foo(): u64 { 0 } // valid! entry functions do not have to be public + } + + module n { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! + // ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } + } + + module other { + public entry fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! + // ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } + } +} + +script { + fun calls_m_foo(): u64 { + 0x42::m::foo() // ERROR! +// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' + } +} +``` + +### 函数名 (Name) + +Function names can start with letters `a` to `z` or letters `A` to `Z`. After the first character, function names can contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, or digits `0` to `9`. + +函数名称可以以字母 `a` 到 `z` 或字母 `A` 到 `Z` 开头。在第一个字符之后,函数名称可以包含下划线 `_`、字母 `a` 到 `z` 、字母 `A` 到 `Z` 或数字 `0` 到 `9`。 + +```move +fun FOO() {} +fun bar_42() {} +fun _bAZ19() {} +``` + +### 类型参数 (Type Parameters) + +After the name, functions can have type parameters + +函数名后可以有类型参数 + +```move +fun id(x: T): T { x } +fun example(x: T1, y: T2): (T1, T1, T2) { (copy x, x, y) } +``` + +For more details, see [Move generics](./generics.md). + +有关更多详细信息,请参阅 [移动泛型](./generics.md)。 + +### 参数 (Parameters) + +Functions parameters are declared with a local variable name followed by a type annotation + +函数参数使用局部变量名,后跟类型标注的方式进行声明。 + +```move +fun add(x: u64, y: u64): u64 { x + y } +``` + +We read this as `x` has type `u64` + +A function does not have to have any parameters at all. + +(上面代码中的函数参数) 我们读为:`x` 参数的类型是 `u64` 。 + +函数可以没有任何参数。 + +```move +fun useless() { } +``` + +This is very common for functions that create new or empty data structures + +在函数中创建新或空的数据结构是常见的用法。 + +```move= +address 0x42 { + module example { + struct Counter { count: u64 } + + fun new_counter(): Counter { + Counter { count: 0 } + } + + } +} +``` + +### Acquires + +When a function accesses a resource using `move_from`, `borrow_global`, or `borrow_global_mut`, the function must indicate that it `acquires` that resource. This is then used by Move's type system to ensure the references into global storage are safe, specifically that there are no dangling references into global storage. + +当一个函数使用 `move_from`、`borrow_global` 或 `borrow_global_mut` 访问资源时,则该函数必须表明它 `获取(acquires)` 该资源。然后 Move 的类型系统使用它来确保对全局存储的引用是安全的,特别是没有对全局存储的悬垂引用(dangling references)。 + +```move= +address 0x42 { + module example { + + struct Balance has key { value: u64 } + + public fun add_balance(s: &signer, value: u64) { + move_to(s, Balance { value }) + } + + public fun extract_balance(addr: address): u64 acquires Balance { + let Balance { value } = move_from(addr); // acquires needed + value + } + } +} +``` +`acquires` annotations must also be added for transitive calls within the module. Calls to these functions from another module do not need to annotated with these acquires because one module cannot access resources declared in another module--so the annotation is not needed to ensure reference safety. + +`acquires` 标注也必须为模块内有传递性的调用添加。从另一个模块对这些函数的调用不需要使用 `acquires` 进行注释,因为一个模块无法访问在另一个模块中声明的资源——因此不需要用标注来确保引用安全。 + +```move= +address 0x42 { + module example { + + struct Balance has key { value: u64 } + + public fun add_balance(s: &signer, value: u64) { + move_to(s, Balance { value }) + } + + public fun extract_balance(addr: address): u64 acquires Balance { + let Balance { value } = move_from(addr); // acquires needed + value + } + + public fun extract_and_add(sender: address, receiver: &signer) acquires Balance { + let value = extract_balance(sender); // acquires needed here + add_balance(receiver, value) + } + } +} + +address 0x42 { + module other { + fun extract_balance(addr: address): u64 { + 0x42::example::extract_balance(addr) // no acquires needed + } + } +} +``` + +A function can `acquire` as many resources as it needs to + +函数可以根据需要 `acquire` 尽可能多的资源。 + +```move= +address 0x42 { + module example { + use std::vector; + + struct Balance has key { value: u64 } + struct Box has key { items: vector } + + public fun store_two( + addr: address, + item1: Item1, + item2: Item2, + ) acquires Balance, Box { + let balance = borrow_global_mut(addr); // acquires needed + balance.value = balance.value - 2; + let box1 = borrow_global_mut>(addr); // acquires needed + vector::push_back(&mut box1.items, item1); + let box2 = borrow_global_mut>(addr); // acquires needed + vector::push_back(&mut box2.items, item2); + } + } +} +``` + +### 返回类型 (Return type) + +After the parameters, a function specifies its return type. + +在参数之后,函数指定其返回类型。 + +```move +fun zero(): u64 { 0 } +``` + +Here `: u64` indicates that the function's return type is `u64`. + +Using tuples, a function can return multiple values + +这里 `: u64` 表示函数的返回类型是 `u64`。 + +使用元组,一个函数可以返回多个值: + +```move +fun one_two_three(): (u64, u64, u64) { (0, 1, 2) } +``` + +If no return type is specified, the function has an implicit return type of unit `()`. These functions are equivalent + +如果未指定返回类型,则该函数具有隐式返回类型单值 `()`。这些函数是等价的: + +```move +fun just_unit(): () { () } +fun just_unit() { () } +fun just_unit() { } +``` + +`script` functions must have a return type of unit `()` + +`script` 函数的返回类型必须为单值 `()`(不能是任何其他类型,例如 `bool`、`u64` 等,注者注): + +```move +script { + fun do_nothing() { + } +} +``` + +As mentioned in the [tuples section](./tuples.md), these tuple "values" are virtual and do not exist at runtime. So for a function that returns unit `()`, it will not be returning any value at all during execution. + +如[元组部分](./tuples.md)所述,这些元组“值”是虚拟的(virtual),且在运行时不存在。因此,对于返回单值 `()` 的函数,它在执行期间根本不会返回任何值。 + +### Function body (函数体) + +A function's body is an expression block. The return value of the function is the last value in the sequence + +函数体是一个表达式块。函数的返回值是序列中最后一个表达式的值。 + +```move= +fun example(): u64 { + let x = 0; + x = x + 1; + x // returns 'x' +} +``` + +See [the section below for more information on returns](#returning-values) + +请参阅[有关返回值的更多信息](#returning-values) + +For more information on expression blocks, see [Move variables](./variables.md). + +有关表达式块的更多信息,请参阅 [Move variables](./variables.md)。 + +### Native Functions + +Some functions do not have a body specified, and instead have the body provided by the VM. These functions are marked `native`. + +Without modifying the VM source code, a programmer cannot add new native functions. Furthermore, it is the intent that `native` functions are used for either standard library code or for functionality needed for the given Move environment. + +Most `native` functions you will likely see are in standard library code such as `vecto + +有些函数没有函数体,而是由 Move VM 提供的函数体。这些函数被标记为 `native`。 + +如果不修改 Move VM 源代码,程序员就无法添加新的 `native` 函数。此外,`native` 函数的意图是用于标准库代码或 Move 环境所需的基础功能。 + +你看到的大多数 `native` 函数可能都在标准库代码中,例如 `vector` + +```move= +module std::vector { + native public fun empty(): vector; + ... +} +``` + +## 调用 (Calling) + +When calling a function, the name can be specified either through an alias or fully qualified + +调用函数时,名称可以通过别名或完全限定名指定 + +```move= +address 0x42 { + module example { + public fun zero(): u64 { 0 } + } +} + +script { + use 0x42::example::{Self, zero}; + fun call_zero() { + // With the `use` above all of these calls are equivalent + 0x42::example::zero(); + example::zero(); + zero(); + } +} +``` + +When calling a function, an argument must be given for every parameter. + +调用函数时,每个参数必须指定一个值。 + +```move= +address 0x42 { + module example { + public fun takes_none(): u64 { 0 } + public fun takes_one(x: u64): u64 { x } + public fun takes_two(x: u64, y: u64): u64 { x + y } + public fun takes_three(x: u64, y: u64, z: u64): u64 { x + y + z } + } +} + +script { + use 0x42::example; + fun call_all() { + example::takes_none(); + example::takes_one(0); + example::takes_two(0, 1); + example::takes_three(0, 1, 2); + } +} +``` + +Type arguments can be either specified or inferred. Both calls are equivalent. + +函数的类型参数可以被指定或推断出来。以下两个调用是等价的。 + +```move= +address 0x42 { + module example { + public fun id(x: T): T { x } + } +} + +script { + use 0x42::example; + fun call_all() { + example::id(0); + example::id(0); + } +} +``` + +For more details, see [Move generics](./generics.md). + +有关更多详细信息,请参阅 [Move generics](./generics.md)。 + + +## Returning values (返回值) + +The result of a function, its "return value", is the final value of its function body. For example + +一个函数的结果,也就是它的“返回值”,是函数体的最后一个值。例如: + +```move= +fun add(x: u64, y: u64): u64 { + x + y +} +``` + +[As mentioned above](#function-body), the function's body is an [expression block](./variables.md). The expression block can sequence various statements, and the final expression in the block will be be the value of that block + +[如上所述](#function-body),函数体是一个[表达式块](./variables.md)。表达式块中可以有各种各种语句,块中最后一个表达式将是该表达式块的值。 + +```move= +fun double_and_add(x: u64, y: u64): u64 { + let double_x = x * 2; + let double_y = y * 2; + double_x + double_y +} +``` + +The return value here is `double_x + double_y` + +这里的返回值是 `double_x + double_y` + +### `return` 表达式 (`return` expression) + +A function implicitly returns the value that its body evaluates to. However, functions can also use the explicit `return` expression: + +函数隐式返回其函数体计算的值。但是,函数也可以使用显式的 `return` 表达式: + +```move +fun f1(): u64 { return 0 } +fun f2(): u64 { 0 } +``` + + +These two functions are equivalent. In this slightly more involved example, the function subtracts two `u64` values, but returns early with `0` if the second value is too large: + +这两个功能是等价的。在下面这个稍微复杂的示例中,该函数返回两个 `u64` 值相减的结果,但如果第二个值大于第一个值,则提前返回 `0` : + +```move= +fun safe_sub(x: u64, y: u64): u64 { + if (y > x) return 0; + x - y +} +``` + +Note that the body of this function could also have been written as `if (y > x) 0 else x - y`. + +However `return` really shines is in exiting deep within other control flow constructs. In this example, the function iterates through a vector to find the index of a given value: + +请注意,这个函数的函数体也可以写成 `if (y > x) 0 else x - y`。 + +然而,`return` 真正的亮点在于在其他控制流结构的深处退出。在此示例中,函数遍历数组以查找给定值的索引: + +```move= +use std::vector; +use std::option::{Self, Option}; +fun index_of(v: &vector, target: &T): Option { + let i = 0; + let n = vector::length(v); + while (i < n) { + if (vector::borrow(v, i) == target) return option::some(i); + i = i + 1 + }; + + option::none() +} +``` + +Using `return` without an argument is shorthand for `return ()`. That is, the following two functions are equivalent: + +使用不带参数的 `return` 是 `return ()` 的简写。即以下两个函数是等价的: + +```move +fun foo() { return } +fun foo() { return () } +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/generics.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/generics.md new file mode 100644 index 000000000..c5553d269 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/generics.md @@ -0,0 +1,422 @@ +# 泛型 + +泛型可用于定义具有不同输入数据类型的函数和结构体。这种语言特性有时被称为*参数多态*(parametric polymorphism)。在 Move 中,我们经常将术语泛型与类型形参(type parameter)和类型实参(type argument)互换使用。*(有些书籍的中文翻译通常将 type parameter 和 type argument 不加以区别地翻译为“类型参数”,译者注)* + +泛型通常用于库(library)代码中,例如向量中,声明适用于任何可能的实例化(满足指定约束)的代码。在其他框架中,泛型代码有时可用多种不同的方式与全局存储进行交互,这些方式有着相同的实现。 + +## 声明类型参数 + +函数和结构体都可以在其签名中带上类型参数列表,由一对尖括号括起来 `<...>`。 + +### 泛型函数 + +函数的类型参数放在函数名称之后和(值)参数列表之前。以下代码定义了一个泛型标识函数,该函数接受任何类型的值并返回原值。 + +```move +fun id(x: T): T { + // 此类型标注是不必要但有效的 + (x: T) +} +``` + +一旦定义,类型参数 `T` 就可以在参数类型、返回类型和函数体内使用。 + +### 泛型结构体 + +结构体的类型参数放在结构名称之后,可用于命名字段的类型。 + +```move +struct Foo has copy, drop { x: T } + +struct Bar has copy, drop { + x: T1, + y: vector, +} +``` + +请注意,[未使用的类型参数](#未使用的类型参数)。 + +## 类型实参 + +### 调用泛型函数 + +调用泛型函数时,可以在由一对尖括号括起来的列表中为函数的类型形参指定类型实参。 + +```move +fun foo() { + let x = id(true); +} +``` + +如果你不指定类型实参,Move 的[类型推断](#类型推断)(功能)将为你提供它们。 + +### 使用泛型结构体 + +类似地,在构造或销毁泛型类型的值时,可以为结构体的类型参数附加一个类型实参列表。 + +```move +fun foo() { + let foo = Foo { x: true }; + let Foo { x } = foo; +} +``` + +如果你不指定类型实参,Move 的[类型推断](#类型推断)(功能)将为你提供它们。 + +### 类型实参不匹配 + +如果你指定类型实参并且它们与提供的实际值冲突,则会报错: + +```move +fun foo() { + let x = id(true); // 错误!true 不是 u64 +} +``` + +同样地: + +```move +fun foo() { + let foo = Foo { x: 0 }; // 错误!0 不是布尔值 + let Foo
{ x } = foo; // 错误!bool 与 address 不兼容 +} +``` + +## 类型推断 + +在大多数情况下,Move 编译器能够推断类型实参,因此你不必显式地写下它们。如果我们省略类型实参,上面的例子会是这样的: + +```move +fun foo() { + let x = id(true); + // ^ 被推断为 + + let foo = Foo { x: true }; + // ^ 被推断为 + + let Foo { x } = foo; + // ^ 被推断为 +} +``` + +注意:当编译器无法推断类型时,你需要手动标注它们。一个常见的场景是调用一个函数,其类型参数只出现在返回位置。 + +```move +address 0x2 { +module m { + using std::vector; + + fun foo() { + // let v = vector::new(); + // ^ 编译器无法确定元素类型。 + + let v = vector::new(); + // ^~~~~ 必须手动标注。 + } +} +} +``` + +但是,如果稍后在该函数中使用该返回值,编译器将能够推断其类型: + +```move +address 0x2 { +module m { + using std::vector; + + fun foo() { + let v = vector::new(); + // ^ 被推断为 + vector::push_back(&mut v, 42); + } +} +} +``` + +## 未使用的类型参数 + +对于结构体定义,未使用的类型参数是没有出现在结构体定义的任何字段中,但在编译时静态检查的类型参数。Move 允许未使用的类型参数,因此以下结构体定义有效: + +```move +struct Foo { + foo: u64 +} +``` + +这在对某些概念建模时会很方便。这是一个例子: + +```move +address 0x2 { +module m { + // 货币说明符 + struct Currency1 {} + struct Currency2 {} + + // 可以使用货币说明符类型实例化的泛型钱币类型。 + // 例如 Coin, Coin 等。 + struct Coin has store { + value: u64 + } + + // 泛型地编写有关所有货币的代码 + public fun mint_generic(value: u64): Coin { + Coin { value } + } + + // 具体编写关于一种货币的代码 + public fun mint_concrete(value: u64): Coin { + Coin { value } + } +} +} +``` + +在此示例中,`struct Coin` 是类型参数为 `Currency` 的泛型结构体,该参数指定钱币的货币(类型),并允许将代码泛型地写入任何货币或具体地写入特定货币。即使 `Currency` 类型参数未出现在 `Coin` 中定义的任何字段中,这种通用性也适用。 + +### 虚类型参数 + +在上面的例子中,虽然 `struct Coin` 要求有 `store` 能力,但 `Coin` 和 `Coin` 都没有 `store` 能力。这实际是因为[条件能力与泛型类型](./abilities.md#条件能力与泛型类型)的规则以及 `Currency1` 和 `Currency2` 没有 `store` 能力,尽管它们甚至没有在 `struct Coin` 的结构体中使用。这可能会导致一些不合意的后果。例如,我们无法将 `Coin` 放入全局存储中的钱包。 + +一种可能的解决方案是向 `Currency1` 和 `Currency2` 添加伪能力(spurious ability)标注(例如:`struct Currency1 has store {}`)。但是,这可能会导致错误(bug)或安全漏洞,因为它削弱了类型,引入了不必要的能力声明。例如,我们永远不会期望全局存储中的资源有一个类型为 `Currency1` 的字段,但是通过伪 `store` 能力这是有可能的。此外,伪标注具有传染性,需要在许多未使用类型参数的泛型函数上也包含必要的约束。 + +虚类型(phantom type)参数解决了这个问题。未使用的类型参数可以标记为 *phantom* 类型参数,不参与结构体的能力推导。这样,在派生泛型类型的能力时,不考虑虚类型参数的实参,从而避免了对伪能力标注的需要。为了使这个宽松的规则合理,Move 的类型系统保证声明为 `phantom` 的参数要么在结构体定义根本不使用,要么仅用作声明为 `phantom` 的类型参数的实参。 + +#### 声明 + +在结构定义中,可以通过在声明前添加 `phantom` 关键字来将类型参数声明为 phantom。如果一个类型参数被声明为 phantom,我们就说它是一个虚类型参数。在定义结构时,Move 的类型检查器确保每个虚类型参数要么未在结构定义中使用,要么仅用作虚类型参数的实参。 + +更正式地说,如果一个类型被用作虚类型参数的实参,我们说该类型出现在_虚位置_。有了这个定义,正确使用虚参数的规则可以指定如下:**虚类型参数只能出现在虚位置**。 + +以下两个示例显示了虚参数的合法使用。在第一个中,结构定义中根本没有使用参数 `T1`。在第二个中,参数 `T1` 仅用作虚类型参数的实参。 + +```move +struct S1 { f: u64 } + ^^ + Ok: T1 没有出现在结构定义中 + +struct S2 { f: S1 } + ^^ + Ok: T1 出现在虚位置 +``` + +以下代码展示违反规则的示例: + +```move +struct S1 { f: T } + ^ + 错误:不是虚位置 + +struct S2 { f: T } + +struct S3 { f: S2 } + ^ + 错误:不是虚位置 +``` + +#### 实例化 + +实例化结构时,在派生结构能力时排除虚参数的实参。例如,考虑以下代码: + +```move +struct S has copy { f: T1 } +struct NoCopy {} +struct HasCopy has copy {} +``` + +现在考虑类型 `S`。因为 `S` 是用 `copy` 定义的,并且所有非虚参数都有 copy 能力,所以 `S` 也有 copy 能力。 + +#### 具有能力约束的虚类型参数 + +能力约束和虚类型参数是正交特征,虚参数可以用能力约束来声明。当实例化具有能力约束的虚类型参数时,类型实参必须满足该约束,即使该参数是虚的(phantom)。例如,以下定义是完全有效的: + +```move +struct S {} +``` + +通常用来限制应用并且 `T` 只能用具有 `copy` 的实参实例化。 + +## 约束 + +在上面的示例中,我们演示了如何使用类型参数来定义稍后可以由调用者插入的“未知”类型。然而,这意味着类型系统几乎没有关于类型的信息,并且必须以非常保守的方式执行检查。在某种意义上,类型系统必须为不受约束的泛型假设最坏的情况。简单地说,默认泛型类型参数没有[能力](./abilities.md)。 + +这就是约束发挥作用的地方:它们提供了一种方法来指定这些未知类型具有哪些属性,以便类型系统可以允许在其他情况下不安全的操作。 + +### 声明约束 + +可以使用以下语法对类型参数施加约束。 + +```move +// T 是类型参数的名称 +T: (+ )* +``` + +`` 可以是四种[能力](./abilities.md)中的任何一种,一个类型参数可以同时被多种能力约束。因此,以下所有内容都是有效的类型参数声明: + +```move +T: copy +T: copy + drop +T: copy + drop + store + key +``` + +### 验证约束 + +在调用点检查约束,所以下面的代码不会编译。 + +```move +struct Foo { x: T } + +struct Bar { x: Foo } +// ^ 错误!u8 没有 'key' + +struct Baz { x: Foo } +// ^ 错误! t 没有 'key' +``` + +```move +struct R {} + +fun unsafe_consume(x: T) { + // 错误!x 没有 'drop' +} + +fun consume(x: T) { + // 合法! + // x 会被自动删除 +} + +fun foo() { + let r = R {}; + consume(r); + // ^ 错误!r 没有 'drop' +} +``` + +```move +struct R {} + +fun unsafe_double(x: T) { + (copy x, x) + // 错误!x 没有 'copy' +} + +fun double(x: T) { + (copy x, x) // 合法! +} + +fun foo(): (R, R) { + let r = R {}; + double(r) + // ^ 错误!R 没有 'error' +} +``` + +有关详细信息,请参阅有关[条件能力与泛型类型](./abilities.md#conditional-abilities-and-generic-types)。 + +## 递归的限制 + +### 递归结构体 + +泛型结构不能直接或间接包含相同类型的字段,即使具有不同类型的参数也是如此。以下所有结构定义均无效: + +```move +struct Foo { + x: Foo // 错误!'Foo' 包含 'Foo' +} + +struct Bar { + x: Bar // 错误!'Bar' 包含 'Bar' +} + +// 错误!'A' 和 'B' 形成一个循环,这也是不允许的。 +struct A { + x: B +} + +struct B { + x: A + y: A +} +``` + +### 高级主题:类型级递归 + +Move 允许递归调用泛型函数。然而,当与泛型结构体结合使用时,在某些情况下这可能会创建无限数量的类型,这意味着会给编译器、虚拟机(mv)和其他语言组件增加不必要的复杂性。因此,这样的递归是被禁止的。 + +被允许的用法: + +```move +address 0x2 { +module m { + struct A {} + + // 有限多种类型 —— 允许。 + // foo -> foo -> foo -> ... is valid + fun foo() { + foo(); + } + + // 有限多种类型 —— 允许。 + // foo -> foo> -> foo> -> ... is valid + fun foo() { + foo>(); + } +} +} +``` + +不被允许的用法: + +```move +address 0x2 { +module m { + struct A {} + + // 无限多种类型 —— 不允许。 + // 错误! + // foo -> foo> -> foo>> -> ... + fun foo() { + foo>(); + } +} +} +``` + +```move +address 0x2 { +module n { + struct A {} + + // 无限多种类型 —— 不允许。 + // 错误! + // foo -> bar -> foo> + // -> bar, T2> -> foo, A> + // -> bar, A> -> foo, A>> + // -> ... + fun foo() { + bar(); + } + + fun bar { + foo>(); + } +} +} +``` + +请注意,类型级递归的检查基于对调用点的保守分析,所以不考虑控制流或运行时值。 + +```move +address 0x2 { +module m { + struct A {} + + fun foo(n: u64) { + if (n > 0) { + foo>(n - 1); + }; + } +} +} +``` + +上面示例中的函数在技术上将终止任何给定的输入,因此只会创建有限多种类型,但它仍然被 Move 的类型系统视为无效的。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/global-storage-operators.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/global-storage-operators.md new file mode 100644 index 000000000..d31b2959f --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/global-storage-operators.md @@ -0,0 +1,312 @@ +# 全局存储 - 操作(Global Storage - Operators) + +Move programs can create, delete, and update [resources](./structs-and-resources.md) in global storage using the following five instructions: + +Move程序可以使用下面五种指令创建、删除、更新全局存储中的[资源](./structs-and-resources.md): + +| Operation | Description | Aborts? | +---------------------------------------- |---------------------------------------------------------------- |---------------------------------------- | +|`move_to(&signer,T)` | Publish `T` under `signer.address` | If `signer.address` already holds a `T` | +|`move_from(address): T` | Remove `T` from `address` and return it | If `address` does not hold a `T` | +|`borrow_global_mut(address): &mut T` | Return a mutable reference to the `T` stored under `address` | If `address` does not hold a `T` | +|`borrow_global(address): &T` | Return an immutable reference to the `T` stored under `address` | If `address` does not hold a `T` | +|`exists(address): bool` | Return `true` if a `T` is stored under `address` | Never + +| 操作符 | 描述 | 出错 | +---------------------------------------- |------------------------------------------------------ |---------------------------------- | +|`move_to(&signer,T)` | 在 `signer.address` 下发布 `T` | 如果 `signer.address` 已经存在 `T` | +|`move_from(address): T` | 从 `address` 下删除 `T` 并返回 | 如果 `address` 下没有 `T` | +|`borrow_global_mut(address): &mut T` | 返回 `address` 下 `T` 的可变引用 mutable reference | 如果 `address` 下没有 `T` | +|`borrow_global(address): &T` | 返回 `address` 下 `T` 的不可变引用 immutable reference | 如果 `address` 下没有 `T` | +|`exists(address): bool` | 返回 `address` 下的 `T` | 永远不会 | + | + +Each of these instructions is parameterized by a type `T` with the [`key` ability](./abilities.md). However, each type `T` *must be declared in the current module*. This ensures that a resource can only be manipulated via the API exposed by its defining module. The instructions also take either an [`address`](./address.md) or [`&signer`](./signer.md) representing the account address where the resource of type `T` is stored. + +每个指令的参数 `T` 都具有 [`key` 能力](./abilities.md)。然而,类型 `T` *必须在当前模块*中声明。这确保资源只能通过当前模块暴露的 API 来操作。指令在存储 `T` 类型资源的同时,使用 [`address`](./address.md) 或 [`&signer`](./signer.md) 表示账户地址。 + + +## 资源参考(References to resources) + +References to global resources returned by `borrow_global` or `borrow_global_mut` mostly behave like references to local storage: they can be extended, read, and written using ordinary [reference operators](./references.md) and passed as arguments to other function. However, there is one important difference between local and global references: **a function cannot return a reference that points into global storage**. For example, these two functions will each fail to compile: + +`borrow_global` 或 `borrow_global_mut` 指令返回的全局资源引用在大多数情况下类似本地存储的引用:它们可以通过[引用操作](./references.md)进行拓展、读和写,也可以作为其它函数的参数。然而本地引用和全局引用有个重要差异:**函数不能返回指向全局存储的引用**。例如,下面两个函数编译会失败: + + +```move +struct R has key { f: u64 } +// 不能编译 // will not compile +fun ret_direct_resource_ref_bad(a: address): &R { + borrow_global(a) // error! +} +// 也不能编译 // also will not compile +fun ret_resource_field_ref_bad(a: address): &u64 { + &borrow_global(a).f // error! +} +``` + +Move must enforce this restriction to guarantee absence of dangling references to global storage. [This](#reference-safety-for-global-resources) section contains much more detail for the interested reader. + +Move必须强制这种限制来保证全局存储引用不会出现空引用。对于感兴趣的读者,[此节](#全局资源引用安全)包含了更多的细节。 + + +## 使用泛型的全局存储操作(Global storage operators with generics) + +Global storage operations can be applied to generic resources with both instantiated and uninstantiated generic type parameters: + +全局存储操作可以与实例化和未实例化的泛型资源参数使用: + + +```move +struct Container has key { t: T } + +/// 发布用于存储调用者提供 T 类型对象的 Container /// Publish a Container storing a type T of the caller's choosing +fun publish_generic_container(account: &signer, t: T) { + move_to>(account, Container { t }) +} + +/// 发布存储 u64 类型的 Container /// Publish a container storing a u64 +fun publish_instantiated_generic_container(account: &signer, t: u64) { + move_to>(account, Container { t }) +} +``` + +The ability to index into global storage via a type parameter chosen at runtime is a powerful Move feature known as *storage polymorphism*. For more on the design patterns enabled by this feature, see [Move generics](./generics.md). + +能够通过参数类型在运行时中索引全局存储的能力是 Move 的强大特性,该特性称之为*存储多态性*。关于此特性更多的设计模式,请参考[Move泛型](./generics.md)这节。 + +## 示例: `Counter` (Example: `Counter`) + +The simple `Counter` module below exercises each of the five global storage operators. The API exposed by this module allows: + +- Anyone to publish a `Counter` resource under their account +- Anyone to check if a `Counter` exists under any address +- Anyone to read or increment the value of a `Counter` resource under any address +- An account that stores a `Counter` resource to reset it to zero +- An account that stores a `Counter` resource to remove and delete it + +下面简单的 `Counter` 模块使用五种全局存储操作。该模块暴露的API允许: + +- 任何人可以在他们的账户下发布 `Counter` 资源。 +- 任何人可以检查任何地址下是否包含 `Counter`。 +- 任何人可以读或增加任何地址下的 `Counter` 值。 +- 存储 `Counter` 资源的账号可以将其重置为 0。 +- 存储 `Counter` 资源的账号可以删除该对象。 + +```move +address 0x42 { +module counter { + use std::signer; + + /// 包含整数的资源 /// Resource that wraps an integer counter + struct Counter has key { i: u64 } + + /// 给定账户下发布带有 `i` 值的 `Counter` 资源 /// Publish a `Counter` resource with value `i` under the given `account` + public fun publish(account: &signer, i: u64) { + // “打包"(创建)Counter 资源。这是需要授权的操作,只能在声明 `Counter` 资源的此模块内执行。 // "Pack" (create) a Counter resource. This is a privileged operation that can only be done inside the module that declares the `Counter` resource + move_to(account, Counter { i }) + } + + /// 读取 `addr` 地址下 `Counter` 内的值 /// Read the value in the `Counter` resource stored at `addr` + public fun get_count(addr: address): u64 acquires Counter { + borrow_global(addr).i + } + + /// 增加 `addr` 地址下 `Counter` 内的值 /// Increment the value of `addr`'s `Counter` resource + public fun increment(addr: address) acquires Counter { + let c_ref = &mut borrow_global_mut(addr).i; + *c_ref = *c_ref + 1 + } + + /// 将 `account` 的 `Counter` 重置为 0 /// Reset the value of `account`'s `Counter` to 0 + public fun reset(account: &signer) acquires Counter { + let c_ref = &mut borrow_global_mut(signer::address_of(account)).i; + *c_ref = 0 + } + + /// 删除 `account` 的 `Counter` 资源并返回其内值 /// Delete the `Counter` resource under `account` and return its value + public fun delete(account: &signer): u64 acquires Counter { + // 删除 Counter 资源 // remove the Counter resource + let c = move_from(signer::address_of(account)); + // 将 `Counter` 资源“拆”为字段。这是需要授权的操作,只能在声明 `Counter` 资源的此模块内执行。 // "Unpack" the `Counter` resource into its fields. This is a privileged operation that can only be done inside the module that declares the `Counter` resource + let Counter { i } = c; + i + } + + /// 如果 `addr` 下包含 `Counter` 资源,则返回 `true`。 /// Return `true` if `addr` contains a `Counter` resource + public fun exists(addr: address): bool { + exists(addr) + } +} +} +``` + +## `acquires` 函数标注(Annotating functions with `acquires`) + +In the `counter` example, you might have noticed that the `get_count`, `increment`, `reset`, and `delete` functions are annotated with `acquires Counter`. A Move function `m::f` must be annotated with `acquires T` if and only if: + +- The body of `m::f` contains a `move_from`, `borrow_global_mut`, or `borrow_global` instruction, or +- The body of `m::f` invokes a function `m::g` declared in the same module that is annotated with `acquires` + +在 `counter` 例子中,可以注意到 `get_count`、`increment`、`reset` 和 `delete` 方法都使用 `acquires Counter` 进行标注。函数 `m::f` 在且仅在下述情况必须使用 `acquires T` 进行标注: + +- `m::f` 的主体包含 `move_from`、`borrow_global_mut` 或 `borrow_global` 指令调用 +- `m::f` 的主体调用了同模块内被 `acquires` 注解的 `m::g` 的函数 + +For example, the following function inside `Counter` would need an `acquires` annotation: + +例如,下面 `Counter` 内的函数需要使用 `acquires` 标注: + +```move +// 由于 `increment` 使用了 `acquires` 标注,所以函数需要 `acquires` // Needs `acquires` because `increment` is annotated with `acquires` +fun call_increment(addr: address): u64 acquires Counter { + counter::increment(addr) +} +``` + +However, the same function *outside* `Counter` would not need an annotation: + +然而,在 `Counter` *外面*的函数则不需要进行标注: + + +```move +address 0x43 { +module m { + use 0x42::counter; + + // 可以,仅在函数声明在同一模块内时需要标注 // Ok. Only need annotation when resource acquired by callee is declared in the same module + fun call_increment(addr: address): u64 { + counter::increment(addr) + } +} +} +``` + +If a function touches multiple resources, it needs multiple `acquires`: + +如果函数需要多个资源,`acquires` 则需要多个参数: + +```move= +address 0x42 { +module two_resources { + struct R1 has key { f: u64 } + struct R2 has key { g: u64 } + + fun double_acquires(a: address): u64 acquires R1, R2 { + borrow_global(a).f + borrow_global.g + } +} +} +``` + +The `acquires` annotation does not take generic type parameters into account: + +`acquires` 标注不会将泛型类型参数纳入声明中: + + +```move= +address 0x42 { +module m { + struct R has key { t: T } + + // 效果为 `acquires R` 而不是 `acquires R` // `acquires R`, not `acquires R` + fun acquire_generic_resource(a: addr) acquires R { + let _ = borrow_global>(a); + } + + // 效果为 `acquires R` 而不是 `acquiresR` // `acquires R`, not `acquires R + fun acquire_instantiated_generic_resource(a: addr) acquires R { + let _ = borrow_global>(a); + } +} +} +``` + +Finally: redundant `acquires` are not allowed. Adding this function inside `Counter` will result in a compilation error: + +最后:不允许使用不必要的 `acquires`。在 `Counter` 内添加下述方法将会导致编译错误: + + +```move +// 下面代码不会编译,因为函数体没有使用全局存储指令也没调用使用 `acquires` 注解的函数 // This code will not compile because the body of the function does not use a global storage instruction or invoke a function with `acquires` +fun redundant_acquires_bad() acquires Counter {} +``` + +For more information on `acquires`, see [Move functions](./functions.md). + +关于 `acquires` 更多信息,参见 [Move 函数](./functions.md)。 + +## 全局资源引用安全(Reference Safety For Global Resources) + +Move prohibits returning global references and requires the `acquires` annotation to prevent dangling references. This allows Move to live up to its promise of static reference safety (i.e., no dangling references, no `null` or `nil` dereferences) for all [reference](./references.md) types. + +Move 禁止返回全局引用并且需要使用 `acquires` 标注来防止空引用。这使 Move 保证了所有[引用](./references.md)类型的静态引用安全性(例如,没有空引用、不会解引用 `null` 或 `nil` 对象)。 + +This example illustrates how the Move type system uses `acquires` to prevent a dangling reference: + +这个例子展示了 Move 类型系统如何通过使用 `acquires` 来防止空引用: + +```move= +address 0x42 { +module dangling { + struct T has key { f: u64 } + + fun borrow_then_remove_bad(a: address) acquires T { + let t_ref: &mut T = borrow_global_mut(a); + let t = remove_t(a); // 类型系统不允许 t_ref 这种空引用 // type system complains here + // t_ref now dangling! + let uh_oh = *&t_ref.f + } + + fun remove_t(a: address): T acquires T { + move_from(a) + } + +} +} +``` + +In this code, line 6 acquires a reference to the `T` stored at address `a` in global storage. The callee `remove_t` then removes the value, which makes `t_ref` a dangling reference. + +代码中第六行获取了 `a` 地址在全局存储中 `T` 类型资源的引用。`remove_t` 调用删除了该值,使 `t_ref` 变成空引用。 + + +Fortunately, this cannot happen because the type system will reject this program. The `acquires` annotation on `remove_t` lets the type system know that line 7 is dangerous, without having to recheck or introspect the body of `remove_t` separately! + +幸运的是,由于类型系统拒绝编译程序导致这种情况不会发生。`remove_t` 方法的 `acquires` 标注让类型系统知道第七行是危险的,不需要再分析 `remove_t` 的函数体。 + +The restriction on returning global references prevents a similar, but even more insidious problem: + +禁止返回全局引用的限制同时也防止了类似却更隐晦的问题: + +```move= +address 0x42 { +module m1 { + struct T has key {} + + public fun ret_t_ref(a: address): &T acquires T { + borrow_global(a) // 报错 类型系统在这不能继续编译 // error! type system complains here + } + + public fun remove_t(a: address) acquires T { + let T {} = move_from(a); + } +} + +module m2 { + fun borrow_then_remove_bad(a: address) { + let t_ref = m1::ret_t_ref(a); + let t = m1::remove_t(a); // t_ref 为空引用 // t_ref now dangling! + } +} +} +``` + +Line 16 acquires a reference to a global resource `m1::T`, then line 17 removes that same resource, which makes `t_ref` dangle. In this case, `acquires` annotations do not help us because the `borrow_then_remove_bad` function is outside of the `m1` module that declares `T` (recall that `acquires` annotations can only be used for resources declared in the current module). Instead, the type system avoids this problem by preventing the return of a global reference at line 6. + +第十六行获取了全局资源 `m1::T` 类型的引用,然后第十七行删除了同一资源,这使 `t_ref` 变成空引用。在这个例子中,`acquires` 标注没有帮助到我们,因为 `borrow_then_remove_bad` 函数在声明了 `T` 类型(回顾 `acquires` 标注只用在声明此类型的模块内)的 `m1` 模块外。然而禁止返回全局引用的规则使第六行避免了这个问题。 + + +Fancier type systems that would allow returning global references without sacrificing reference safety are possible, and we may consider them in future iterations of Move. We chose the current design because it strikes a good balance between expressivity, annotation burden, and type system complexity. + +允许返回全局引用而尽可能不牺牲引用安全的高级类型系统是可行的,我们将会在 Move 未来的迭代过程中考虑此事。我们选择目前的设计方式是因为它很好的平衡了语言表现力、复杂的标注和复杂的类型系统三者的关系。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/global-storage-structure.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/global-storage-structure.md new file mode 100644 index 000000000..763d253d5 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/global-storage-structure.md @@ -0,0 +1,14 @@ +# 全局存储 —— 结构 + +Move 程序的目的是[读取和写入](./global-storage-operators.md)树形的持久全局存储。程序不能访问文件系统、网络或任何此树以外的数据。 + +在伪代码中,全局存储看起来像: + +```move +struct GlobalStorage { + resources: Map<(address, ResourceType), ResourceValue> + modules: Map<(address, ModuleName), ModuleBytecode> +} +``` + +从结构上讲,全局存储是一个[森林(forest)](https://en.wikipedia.org/wiki/Tree_(graph_theory)),这个森林由以账户[地址(`address`)](./address.md)为根的树组成。每个地址可以存储[资源(resource)](./structs-and-resources.md)数据和[模块(module)](./modules-and-scripts.md)代码。如上面的伪代码所示,每个地址(`address`)最多可以存储一个给定类型的资源值,最多可以存储一个给定名称的模块。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/integers.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/integers.md new file mode 100644 index 000000000..a1a70430b --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/integers.md @@ -0,0 +1,214 @@ +# 整数 (Integers) + +Move supports three unsigned integer types: `u8`, `u64`, and `u128`. Values of these types range from 0 to a maximum that depends on the size of the type. + +| Type | Value Range | +| -------------------------------- | ------------------------ | +| Unsigned 8-bit integer, `u8` | 0 to 28 - 1 | +| Unsigned 64-bit integer, `u64` | 0 to 264 - 1 | +| Unsigned 128-bit integer, `u128` | 0 to 2128 - 1 | + + +Move 支持三种无符号整数类型:`u8`、`u64` 和 `u128`。这些类型的值范围从 0 到最大值,最大值的具体取值取决于整数类型。 + +| 类型 | 取值范围 | +|---------------------------|--------------------------| +| 无符号 8位 整数, `u8` | 0 to 28 - 1 | +| 无符号 64位 整数, `u64` | 0 to 264 - 1 | +| 无符号 128位 整数, `u128` | 0 to 2128 - 1 | + + +## 字面值(Literal) + +Literal values for these types are specified either as a sequence of digits (e.g.,`112`) or as hex literals, e.g., `0xFF`. The type of the literal can optionally be added as a suffix, e.g., `112u8`. If the type is not specified, the compiler will try to infer the type from the context where the literal is used. If the type cannot be inferred, it is assumed to be `u64`. + +If a literal is too large for its specified (or inferred) size range, an error is reported. + +(在Move中)这些类型的字面值指定为数字序列(例如:112)或十六进制文字(例如:0xFF), 可以选择将字面值的类型定义为后缀, 例如 `112u8`。如果未指定类型,编译器将尝试从使用字面值的上下文推断类型。如果无法推断类型,则默认为 `u64。 + +如果字面值太大,超出其指定的(或推断的)大小范围,则会报错。 + +### 例如: + +```jsx +// literals with explicit annotations; +let explicit_u8 = 1u8; +let explicit_u64 = 2u64; +let explicit_u128 = 3u128; + +// literals with simple inference +let simple_u8: u8 = 1; +let simple_u64: u64 = 2; +let simple_u128: u128 = 3; + +// literals with more complex inference +let complex_u8 = 1; // inferred: u8 +// right hand argument to shift must be u8 +let _unused = 10 << complex_u8; + +let x: u8 = 0; +let complex_u8 = 2; // inferred: u8 +// arguments to `+` must have the same type +let _unused = x + complex_u8; + +let complex_u128 = 3; // inferred: u128 +// inferred from function argument type +function_that_takes_u128(complex_u128); + +// literals can be written in hex +let hex_u8: u8 = 0x1; +let hex_u64: u64 = 0xCAFE; +let hex_u128: u128 = 0xDEADBEEF; +``` + +## 运算集 (Operations) + +### 算术运算 (Arithmetic) + +Each of these types supports the same set of checked arithmetic operations. For all of these operations, both arguments (the left and right side operands) must be of the same type. If you need to operate over values of different types, you will need to first perform a cast. Similarly, if you expect the result of the operation to be too large for the integer type, perform a cast to a larger size before performing the operation. + +每一种(无符号整数)类型都支持相同算术运算集。对于所有这些运算,两个参数(左侧和右侧操作数)必须是同一类型。如果您需要对不同类型的值进行运算,则需要首先执行强制转换。同样,如果您预计运算结果对于当下整数类型来说太大,请在执行运算之前将之转换为更大的整数类型。 + +All arithmetic operations abort instead of behaving in a way that mathematical integers would not (e.g., overflow, underflow, divide-by-zero). + +| Syntax | Operation | Aborts If | +| ------ | ------------------- | ---------------------------------------- | +| `+` | addition | Result is too large for the integer type | +| `-` | subtraction | Result is less than zero | +| `*` | multiplication | Result is too large for the integer type | +| `%` | modular division | The divisor is `0` | +| `/` | truncating division | The divisor is `0` | + +### [Bitwise](https://move-language.github.io/move/integers.html#bitwise) + +算术运算在遇到异常时将会中止,而不是以上溢、下溢、被零除等数学整数未定义的的方式输出结果。 + +| 句法 | 操作 | 中止条件 | +| ------ | ------------| ---------------------------------------- | +| `+` | 加法 | 结果对于整数类型来说太大了 | +| `-` | 减法 | 结果小于零 | +| `*` | 乘法 | 结果对于整数类型来说太大了 | +| `%` | 取余运算 | 除数为 `0` | +| `/` | 截断除法 | 除数为 `0` | + +### 位运算 (Bitwise) + +The integer types support the following bitwise operations that treat each number as a series of individual bits, either 0 or 1, instead of as numerical integer values. + +Bitwise operations do not abort. + +| Syntax | Operation | Description | +|---------------------|-------------|-------------------------------------------------------| +| `&` | bitwise and | Performs a boolean and for each bit pairwise | +| | | bitwise or | Performs a boolean or for each bit pairwise | +| `^` | bitwise xor | Performs a boolean exclusive or for each bit pairwise | + +整数类型支持下列位运算,即将每个数字视为一系列单独的位:0 或 1,而不是整型数值。 + +位运算不会中止。 + +| 语法 | 操作符 | 描述 | +|---------------------|----------|----------------------------| +| `&` | 按位和 | 对每个位成对执行布尔值和 | +| | | 按位或 | 对每个位成对执行布尔值或 | +| `^` | 按位异或 | 对每个位成对执行布尔值异或 | + +### 位移 (Bit shift) + +Similar to the bitwise operations, each integer type supports bit shifts. But unlike the other operations, the righthand side operand (how many bits to shift by) must *always* be a `u8` and need not match the left side operand (the number you are shifting). + +Bit shifts can abort if the number of bits to shift by is greater than or equal to `8`, `64`, or `128` for `u8`, `u64`, and `u128` respectively. + +| Syntax | Operation | Aborts if | +| ------ | ----------- | ------------------------------------------------------------ | +| `<<` | shift left | Number of bits to shift by is greater than the size of the integer type | +| `>>` | shift right | Number of bits to shift by is greater than the size of the integer type | + +与按位运算类似,每种整数类型都支持位移(bit shifts)。但与其他运算不同的是,右侧操作数(要移位多少位)必须始终是 `u8`  并且不需要与左侧操作数类型(您要移位的数字)匹配。 + +如果要移位的位数分别大于或等于 `8`、`64`, `u128` 或 `128` 的 `u8`, `u64`, 则移位可以中止。 + +| 句法 | 操作 | 中止条件 | +| ------ | ----------- | ------------------------------------------------------------ | +| `<<` | 左移 | 要移位的位数大于整数类型的大小 | +| `>>` | 右移 | 要移位的位数大于整数类型的大小 | + +### 比较运算 (Comparisons) + +Integer types are the *only* types in Move that can use the comparison operators. Both arguments need to be of the same type. If you need to compare integers of different types, you will need to [cast](https://move-language.github.io/move/integers.html#casting) one of them first. + +Comparison operations do not abort. + +| Syntax | Operation | +| ------ | ------------------------ | +| `<` | less than | +| `>` | greater than | +| `<=` | less than or equal to | +| `>=` | greater than or equal to | + +整数类型是 Move 中唯一可以使用比较(Comparisons)运算符的类型。两个参数必须是同一类型。如果您需要比较不同类型的整数,则需要先转换其中一个。 + +比较操作不会中止。 + +| 句法 | 操作 | +| ------ | ------------------------ | +| `<` | 小于 | +| `>` | 大于 | +| `<=` | 小于等于 | +| `>=` | 大于等于 | + +### 相等 (Equality) + +Like all types with [`drop`](https://move-language.github.io/move/abilities.html) in Move, all integer types support the ["equal"](https://move-language.github.io/move/equality.html) and ["not equal"](https://move-language.github.io/move/equality.html) operations. Both arguments need to be of the same type. If you need to compare integers of different types, you will need to [cast](https://move-language.github.io/move/integers.html#casting) one of them first. + +Equality operations do not abort. + +| Syntax | Operation | +| ------ | --------- | +| `==` | equal | +| `!=` | not equal | + +For more details see the section on [equality](https://move-language.github.io/move/equality.html) + +与 Move 中的所有具有[`drop`](./chapter_19_abilities.html)能力的类型一样,所有整数类型都支持 ["equal(等于)"](./chapter_11_equality.html) 和 ["not equal(不等于)](./chapter_11_equality.html)运算。两个参数必须是同一类型。如果您需要比较不同类型的整数,则需要先转换其中一个。 + +相等(Equality)运算不会中止。 + +| 句法 | 操作 | +| ------ | --------- | +| `==` | 等于 | +| `!=` | 不等于 | + +更多细节可以参考[相等]([equality](https://move-language.github.io/move/equality.html))章节。 + +## 转换 (Casting) + +Integer types of one size can be cast to integer types of another size. Integers are the only types in Move that support casting. + +Casts *do not* truncate. Casting will abort if the result is too large for the specified type + +| Syntax | Operation | Aborts if | +| ---------- | ---------------------------------------------------- | -------------------------------------- | +| `(e as T)` | Cast integer expression `e` into an integer type `T` | `e` is too large to represent as a `T` | + +Here, the type of `e` must be `u8`, `u64`, or `u128` and `T` must be `u8`, `u64`, or `u128`. + +For example: + +- `(x as u8)` +- `(2u8 as u64)` +- `(1 + 3 as u128)` + +一种大小的整数类型可以转换为另一种大小的整数类型。整数是 Move 中唯一支持强制转换的类型。 + +强制转换不会截断。如果结果对于指定类型来说太大,则转换将中止。 + +| Syntax | 操作 | 中止条件 | +| ---------- | ---------------------------------------------------- | -------------------------------------- | +| `(e as T)` | 将整数表达式 `e` 转换为整数类型 `T` | `e` 太大而不能表示为 `T` | + +## 所有权 (Ownership) + +As with the other scalar values built-in to the language, integer values are implicitly copyable, meaning they can be copied without an explicit instruction such as [`copy`](https://move-language.github.io/move/variables.html#move-and-copy). + +与语言内置的其他标量值一样,整数值是隐式可复制的,这意味着它们可以在没有明确指令如[`copy`](./variables.md#move-and-copy)的情况下复制。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/introduction.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/introduction.md new file mode 100644 index 000000000..5e3ea6f79 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/introduction.md @@ -0,0 +1,47 @@ +# 引言 (Introduction) + +Welcome to Move, a next generation language for secure, sandboxed, and formally verified programming. Its first use case is for the Diem blockchain, where Move provides the foundation for its implementation. Move allows developers to write programs that flexibly manage and transfer assets, while providing the security and protections against attacks on those assets. However, Move has been developed with use cases in mind outside a blockchain context as well. + +欢迎来到Move的世界,Move是一种安全、沙盒式和形式化验证的下一代编程语言,它的第一个用例是 Diem 区块链(当时名字叫Libra, 脸书团队开发的项目, 译者注), Move 为其实现提供了基础。 Move 允许开发人员编写灵活管理和转移数字资产的程序,同时提供安全保护,防止对那些链上资产的攻击。不仅如此,Move 也可用于区块链世界之外的开发场景。 + +Move takes its cue from [Rust](https://www.rust-lang.org/) by using resource types with move (hence the name) semantics as an explicit representation of digital assets, such as currency. + +Move 的诞生从[Rust](https://www.rust-lang.org/)中吸取了灵感,Move也是因为使用具有移动(move)语义的资源类型作为数字资产(例如货币)的显式表示而得名。 + +## Move是为谁准备的?(Who is Move for?) + +Move was designed and created as a secure, verified, yet flexible programming language. The first use of Move is for the implementation of the Diem blockchain. That said, the language is still evolving. Move has the potential to be a language for other blockchains, and even non-blockchain use cases as well. + +Move语言被设计和创建为安全、可验证, 同时兼顾灵活性的编程语言。Move的第一个应用场景是用于Diem区块链的开发。现在,Move语言仍在不断发展中。Move 还有成为其他区块链,甚至非区块链用例开发语言的潜质。 + +Given custom Move modules will not be supported at the [launch](https://diem.com/white-paper/#whats-next) of the Diem Payment Network (DPN), we are targeting an early Move Developer persona. + +鉴于在 Diem 支付网络 (DPN) [启动](https://diem.com/white-paper/#whats-next)时将不支持自定义 Move 模块(custom Move modules),我们的目标是早期的 Move 开发人员。 + +The early Move Developer is one with some programming experience, who wants to begin understanding the core programming language and see examples of its usage. + +早期的 Move 开发人员应该是具有一定编程经验的程序员,他们愿意了解编程语言核心,并探索它的用法。 + +### 爱好者 (Hobbyists) + +Understanding that the capability to create custom modules on the Diem Payment Network will not be available at launch, the hobbyist Move Developer is interested in learning the intricacies of the language. She will understand the basic syntax, the standard libraries available, and write example code that can be executed using the Move CLI. The Move Developer may even want to dig into understanding how the Move Virtual Machine executes the code she writes. + +作为(Move语言)爱好者角色,首先需要明白在Diem支付网络上创建自定义模块(custom modules)是不可能的,其次,你还要对探索这门语言的复杂性保持兴趣。你将了解基本语法、可用的标准库,并编写可以用的Move CLI执行的示例代码。如果可能,你甚至可以去尝试体验Move虚拟机如何执行你自己编写的代码。 + +### 核心贡献者 (Core Contributor) + +Beyond a hobbyist wanting to stay ahead of the curve for the core programming language is someone who may want to [contribute](https://diem.com/en-US/cla-sign/) directly to Move. Whether this includes submitting language improvements or even, in the future, adding core modules available on the Diem Payment Network, the core contributor will understand Move at a deep level. + +核心贡献者指那些超越爱好者并想在核心编程语言方面保持领先,还直接为 Move 做出[贡献](https://diem.com/en-US/cla-sign/)的人。无论是提交语言改进,甚至未来添加 Diem 支付网络上可用的核心模块等,核心贡献者都将深入了解Move。 + +### Move不适用于哪些人?(Who Move is currently not targeting) + +Currently, Move is not targeting developers who wish to create custom modules and contracts for use on the Diem Payment Network. We are also not targeting novice developers who expect a completely polished developer experience even in testing the language. + +目前,Move 并不适用那些希望在在 Diem 支付网络上创建自定义模块和合约的开发人员。我们也不针对期望在测试语言时就能获得完美开发体验的初学开发者。 + +## 从哪里开始?(Where Do I Start?) + +Begin with understanding [modules and scripts](https://move-language.github.io/move/modules-and-scripts.html) and then work through the [Move Tutorial](https://move-language.github.io/move/creating-coins.html). + +你可以从了解模块和脚本([modules and scripts](./modules-and-scripts.html))开始,然后跟随Move教程([Move Tutorial](./move-tutorial.html))进行练习。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/loops.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/loops.md new file mode 100644 index 000000000..34626ed28 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/loops.md @@ -0,0 +1,215 @@ +# While and Loop + +Move offers two constructs for looping: `while` and `loop`. + +Move 提供了两种循环结构: `while` and `loop`. + +## `while` 循环 + +The `while` construct repeats the body (an expression of type unit) until the condition (an expression of type `bool`) evaluates to `false`. + +Here is an example of simple `while` loop that computes the sum of the numbers from `1` to `n`: + +`while` 会重复执行结构(一个 `unit` 类型的表达式), 直到条件语句(`bool` 类型的表达式)运算结果为 `false`。 + +下面是一个简单的 `while` 循环的例子,计算从 `1` 到 `n` 数字之和: + +```move +fun sum(n: u64): u64 { + let sum = 0; + let i = 1; + while (i <= n) { + sum = sum + i; + i = i + 1 + }; + + sum +} +``` + +Infinite loops are allowed: + +无限循环是被允许的: + +```move= +fun foo() { + while (true) { } +} +``` + +### `break` + +The `break` expression can be used to exit a loop before the condition evaluates to `false`. For example, this loop uses `break` to find the smallest factor of `n` that's greater than 1: + +`break` 表达式可用于在条件计算结果为 `false` 之前退出循环。例如,这个循环使用 `break` 查找 `n` 大于1的最小因子: + +```move +fun smallest_factor(n: u64): u64 { + // assuming the input is not 0 or 1 + let i = 2; + while (i <= n) { + if (n % i == 0) break; + i = i + 1 + }; + + i +} +``` + +The `break` expression cannot be used outside of a loop. + +`break` 表达式不能在循环之外使用。 + +### `continue` + +The `continue` expression skips the rest of the loop and continues to the next iteration. This loop uses `continue` to compute the sum of `1, 2, ..., n`, except when the number is divisible by 10: + +`continue` 表达式跳过当前循环的剩余部分, 并继续下一轮迭代。下面的例子, 使用 `continue` 去计算 `1, 2, ..., n` 的总和,过滤掉不能被10整除的数: + +```move +fun sum_intermediate(n: u64): u64 { + let sum = 0; + let i = 0; + while (i < n) { + i = i + 1; + if (i % 10 == 0) continue; + sum = sum + i; + }; + + sum +} +``` + +The `continue` expression cannot be used outside of a loop. + +`continue` 表达式不能在循环之外使用。 + +### The type of `break` and `continue` + +`break` and `continue`, much like `return` and `abort`, can have any type. The following examples illustrate where this flexible typing can be helpful: + +`break` and `continue`, 和 `return` and `abort` 很相像, 可以是任何类型。下面的例子说明了这种灵活的类型在那些方面有帮助: + +```move +fun pop_smallest_while_not_equal( + v1: vector, + v2: vector, +): vector { + let result = vector::empty(); + while (!vector::is_empty(&v1) && !vector::is_empty(&v2)) { + let u1 = *vector::borrow(&v1, vector::length(&v1) - 1); + let u2 = *vector::borrow(&v2, vector::length(&v2) - 1); + let popped = + if (u1 < u2) vector::pop_back(&mut v1) + else if (u2 < u1) vector::pop_back(&mut v2) + else break; // Here, `break` has type `u64` + vector::push_back(&mut result, popped); + }; + + result +} + +fun pick( + indexes: vector, + v1: &vector
, + v2: &vector
+): vector
{ + let len1 = vector::length(v1); + let len2 = vector::length(v2); + let result = vector::empty(); + while (!vector::is_empty(&indexes)) { + let index = vector::pop_back(&mut indexes); + let chosen_vector = + if (index < len1) v1 + else if (index < len2) v2 + else continue; // Here, `continue` has type `&vector
` + vector::push_back(&mut result, *vector::borrow(chosen_vector, index)) + }; + + result +} +``` + +## `loop`表达式 + +The `loop` expression repeats the loop body (an expression with type `()`) until it hits a `break` + +Without a `break`, the loop will continue forever + +`loop` 表达式重复循环体(类型为unit()的表达式) ,直到遇到 `break` 为止。 + +(下面的代码中)没有 `break`, 循环将一直执行。 + +```move +fun foo() { + let i = 0; + loop { i = i + 1 } +} +``` + +Here is an example that uses `loop` to write the `sum` function: + +这是一个使用 `loop` 编写 `sum` 函数的示例(可与 `while` 循环比较): + +```move +fun sum(n: u64): u64 { + let sum = 0; + let i = 0; + loop { + i = i + 1; + if (i > n) break; + sum = sum + i + }; + + sum +} +``` + +As you might expect, `continue` can also be used inside a `loop`. Here is `sum_intermediate` from above rewritten using `loop` instead of `while` + +正如你所料, `continue` 也可以在 `loop` 中使用。这是上面的 `sum_intermediate` 使用 `loop` 代替 `while` 重写的: + +```move +fun sum_intermediate(n: u64): u64 { + let sum = 0; + let i = 0; + loop { + i = i + 1; + if (i % 10 == 0) continue; + if (i > n) break; + sum = sum + i + }; + + sum +} +``` + +## `while` and `loop` 的类型 + +Move loops are typed expressions. A `while` expression always has type `()`. + +Move 循环是有类型化的表达式。 `while` 表达式始终具有 `()` 类型。 + +```move +let () = while (i < 10) { i = i + 1 }; +``` + +If a `loop` contains a `break`, the expression has type unit `()` + +如果 `loop` 中包含 `break` , 这个表达式的类型则为 unit `()` + + +```move +(loop { if (i < 10) i = i + 1 else break }: ()); +let () = loop { if (i < 10) i = i + 1 else break }; +``` + +If `loop` does not have a `break`, `loop` can have any type much like `return`, `abort`, `break`, and `continue`. + +如果 `loop` 不包含 `break`, `loop` 可以是任何类型, 就像`return`, `abort`, `break`, 和 `continue`。 + +```move +(loop (): u64); +(loop (): address); +(loop (): &vector>); +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/modules-and-scripts.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/modules-and-scripts.md new file mode 100644 index 000000000..9dbca68eb --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/modules-and-scripts.md @@ -0,0 +1,119 @@ +# 模块和脚本 + +Move 有两种不同类型的程序:***模块(Module)***和***脚本(Script)***。模块是定义结构类型以及对这些类型进行操作的函数的库。*结构类型*定义了 Move 的[全局存储](./global-storage-structure.md)的模式,*模块函数*定义了更新存储的规则。模块本身也存储在全局存储中。脚本是[可执行文件](https://en.wikipedia.org/wiki/Executable)的入口点,类似于传统语言中的主函数 `main`。脚本通常调用已发布模块的函数来更新全局存储。脚本是临时代码片段,不会发布在全局存储中。 + +一个 Move 源文件(或**编译单元**)可能包含多个模块和脚本。然而,发布模块或执行脚本都是独立的虚拟机(VM)操作。 + +## 语法 + +### 脚本 + +脚本具有以下结构: + +```text +script { + * + * + fun <[type parameters: constraint]*>([identifier: type]*) +} +``` + +一个 `script` 块必须以它的所有 [`use`](./uses.md) 声明开头,然后是[常量(constant)](./constants.md)声明,最后是主[函数](./functions.md)声明。主函数的名称可以是任意的(也就是说,它不一定命名为 `main`),它是脚本块中唯一的函数,可以有任意数量的参数,并且不能有返回值。下面是每个组件的示例: + +```move +script { + // 导入在命名账户地址 std 上发布的 debug 模块。 + use std::debug; + + const ONE: u64 = 1; + + fun main(x: u64) { + let sum = x + ONE; + debug::print(&sum) + } +} +``` + +脚本(Script)的功能非常有限 —— 它们不能声明友元(friend)、结构类型或访问全局存储。他们的主要作用主要是调用*模块函数*。 + +### 模块 + +模块具有以下结构: + +```text +module
:: { + ( | | | | )* +} +``` + +其中 `
` 是一个有效的[命名或字面量地址](./address.md)。 + +例子: + +```move +module 0x42::test { + struct Example has copy, drop { i: u64 } + + use std::debug; + friend 0x42::another_test; + + const ONE: u64 = 1; + + public fun print(x: u64) { + let sum = x + ONE; + let example = Example { i: sum }; + debug::print(&sum) + } +} +``` + +`module 0x42::test` 这部分指定模块 `test` 将在[全局存储](./global-storage-structure.md)的[账户地址](./address.md) `0x42` 下发布。 + +模块也可以使用[命名地址](./address.md)来声明,例如: + +```move +module test_addr::test { + struct Example has copy, drop { a: address } + + use std::debug; + friend test_addr::another_test; + + public fun print() { + let example = Example { a: @test_addr }; + debug::print(&example) + } +} +``` + +因为命名地址只存在于源语言级别和编译期间,所以命名地址将在字节码级别彻底替换它们的值。例如,如果我们有以下代码: + +```move +script { + fun example() { + my_addr::m::foo(@my_addr); + } +} +``` + +我们在把 `my_addr` 设置为 `0xC0FFEE` 的情况下编译它,那么它在操作上等同于以下内容: + +```move +script { + fun example() { + 0xC0FFEE::m::foo(@0xC0FFEE); + } +} +``` + +然而,在源代码级别,这些是*不等价的* —— 函数 `m::foo` *必须*通过 `my_addr` 命名地址来访问,而不是通过分配给该地址的数值来访问。 + +模块名称可以以字母 `a` 到 `z` 或字母 `A` 到 `Z` 开头。在第一个字符之后,模块名可以包含下划线 `_`、字母 `a` 到 `z`、字母 `A` 到 `Z` 或数字 `0` 到 `9`。 + +```move +module my_module {} +module foo_bar_42 {} +``` + +通常,模块名称以小写字母开头。名为 `my_module` 的模块应该存储在名为 `my_module.move` 的源文件中。 + +`module` 块内的所有元素都可以按任意顺序出现。从根本上说,模块是[`类型(type)`](./structs-and-resources.md)和[`函数(function)`](./functions.md)的集合。[`use`](./uses.md) 关键字用来从其他模块导入类型。[`friend`](./friends.md) 关键字指定一个可信的模块列表。[`const`](./constants.md) 关键字定义了可以在模块函数中使用的私有常量。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/move-tutorial.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/move-tutorial.md new file mode 100644 index 000000000..209d54950 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/move-tutorial.md @@ -0,0 +1,970 @@ +# Move 教程(Move Tutorial) + +Welcome to the Move Tutorial! In this tutorial, we are going to go through some steps of developing Move code including design, implementation, unit testing and formal verification of Move modules. + +欢迎来到 Move 语言教程,在本教程中,我们通过一些具体的步骤进行 Move 语言代码的开发,包括 Move 模块的设计、实现、单元测试和形式化验证。 + +There are nine steps in total: + +- [Step 0: Installation](#Step0) +- [Step 1: Writing my first Move module](#Step1) +- [Step 2: Adding unit tests to my first Move module](#Step2) +- [Step 3: Designing my `BasicCoin` module](#Step3) +- [Step 4: Implementing my `BasicCoin` module](#Step4) +- [Step 5: Adding and using unit tests with the `BasicCoin` module](#Step5) +- [Step 6: Making my `BasicCoin` module generic](#Step6) +- [Step 7: Use the Move prover](#Step7) +- [Step 8: Writing formal specifications for the `BasicCoin` module](#Step8) + +整个过程共包含9个步骤: + +- [Step 0: 安装 Move 开发环境](#Step0) +- [Step 1: 编写第一个 Move 模块(Move Module)](#Step1) +- [Step 2: 给模块(Module)添加单元测试](#Step2) +- [Step 3: 设计自己的 `BasicCoin` 模块(Module)](#Step3) +- [Step 4: `BasicCoin` 模块(Module)的实现](#Step4) +- [Step 5: 给 `BasicCoin` 模块添加单元测试](#Step5) +- [Step 6: 使用泛型(generic)编写 `BasicCoin` 模块](#Step6) +- [Step 7: 使用 `Move prover`](#Step7) +- [Step 8: 为 `BasicCoin` 模块编写形式化规范(formal specifications)](#Step8) + +Each step is designed to be self-contained in the corresponding `step_x` folder. For example, if you would +like to skip the contents in step 1 through 4, feel free to jump to step 5 since all the code we have written +before step 5 will be in `step_5` folder. At the end of some steps, we also include +additional material on more advanced topics. + +其中每一步都被设计为自包含的文件夹, 相应名字为 `step_x`。 例如,如果您愿意跳过 `step 1` 到 `step 4` 的内容,可直接跳到 `step 5`,因为所有在 `step 5` 之前的代码均在在`step_5` 文件夹之下。在部分步骤结束时,我们还引入有关更高级主题的附加资料。 + +Now let's get started! + +好了,我们现在开始! + +## Step 0: 安装 Move 开发环境 (Step 0: Installation) + +If you haven't already, open your terminal and clone [the Move repository](https://github.com/move-language/move): + +如果您还没有安装过 Move,首先打开命令终端(terminal) 并clone [Move代码库](https://github.com/move-language/move): + +```bash +git clone https://github.com/move-language/move.git +``` + +Go to the `move` directory and run the `dev_setup.sh` script: + +进入到 `move` 文件夹下,执行 `dev_setup.sh` 脚本: + +```bash +cd move +./scripts/dev_setup.sh -ypt +``` + +Follow the script's prompts in order to install all of Move's dependencies. + +The script adds environment variable definitions to your `~/.profile` file. +Include them by running this command: + +根据脚本命令的提示,按顺序安装 Move 的所有依赖项。 +脚本将会将(move命令所在路径)环境变量写入到 `~/.profile` 文件中。 + +执行如下命令使环境变量生效: + +```bash +source ~/.profile +```` + +Next, install Move's command-line tool by running this commands: + +然后执行如下命令来安装 Move 命令行工具: + +```bash +cargo install --path language/tools/move-cli +``` + +You can check that it is working by running the following command: + +通过如下运行命令可以检查 move 命令是否可正常: + +```bash +move --help +``` +You should see something like this along with a list and description of a number of commands: + +您应该会看到类似这样的内容以及许多命令的列表和描述: + +``` +move-package +Execute a package command. Executed in the current directory or the closest containing Move package + +USAGE: + move [OPTIONS] + +OPTIONS: + --abi Generate ABIs for packages +... +``` + +If you want to find what commands are available and what they do, running +a command or subcommand with the `--help` flag will print documentation. + +如果想了解有支持哪引命令及其作用, 执行命令或子命令时添加 `--help` 标记,此时会打印帮助文档。 + +Before running the next steps, `cd` to the tutorial directory: + +在执行下一步骤之前,请先执行 `cd` 命令进入到教程对应目录下: + +```bash +cd /language/documentation/tutorial +``` + +
+ +Visual Studio Code Move 支持 (Visual Studio Code Move Support) + +There is official Move support for Visual Studio Code. You need to install +the move analyzer first: + +Visual Studio Code 有正式的 Move 语言支持, 您需要先安装 `move analyzer` : + +```bash +cargo install --path language/move-analyzer +``` + +Now you can install the VS extension by opening VS Code, searching for the "move-analyzer" in the Extension Pane, and installing it. More detailed instructions can be found +in the extension's [README](https://github.com/move-language/move/tree/main/language/move-analyzer/editors/code). + +现在您可以打开 VS Code 并安装 Move 扩展插件了,在扩展页面下找到 `move-analyzer` 并安装即可。关于扩展的详细信息可以查看扩展的[README](https://github.com/move-language/move/tree/main/language/move-analyzer/editors/code)。 +
+ +## Step 1: 编写第一个Move模块 (Writing my first Move module) + +Change directory into the [`step_1/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_1/BasicCoin) directory. +You should see a directory called `sources` -- this is the place where all +the Move code for this package lives. You should also see a +`Move.toml` file as well. This file specifies dependencies and other information about +the package; if you're familiar with Rust and Cargo, the `Move.toml` file +is similar to the `Cargo.toml` file, and the `sources` directory similar to +the `src` directory. + +切换当前目录到[`step_1/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_1/BasicCoin)下,您将看到 `sources` 子目录 -- 这个包(package)下所有的 Move 代码都在此目录中,同时您还会看到一个 `Move.toml` 文件。该文件指定当前包的依赖列表和其他信息。 +如果您熟悉 `Rust` 和 `Cargo`,那 `Move.toml` 文件类似 `Cargo.toml` 文件, `sources` 目录类似 `src` 目录(它们的作用是一样的) + +Let's take a look at some Move code! Open up +[`sources/FirstModule.move`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_1/BasicCoin/sources/FirstModule.move) in +your editor of choice. The first thing you'll see is this: + +来一起看看 Move 语言代码内容! 用你的编辑器打开[`sources/FirstModule.move`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_1/BasicCoin/sources/FirstModule.move)文件,会看到如下内容: + +``` +// sources/FirstModule.move +module 0xCAFE::BasicCoin { + ... +} +``` + +This is defining a Move +[module](https://move-language.github.io/move/modules-and-scripts.html). Modules are the +building block of Move code, and are defined with a specific address -- the address that the module can be published under. +In this case, the `BasicCoin` module can only be published under `0xCAFE`. + +这是一个 `Move` [module(模块)](./chpater_1_modules-and-scripts.html)的定义。 +模块是 Move 语言的代码块, 并且它使用指定的地址(address)进行定义 -- 模块只能在该地址下发布。 +当前 `BasicCoin` 模块只能被发布在 `0xCAFE` 地址下。 + +Let's now take a look at the next part of this file where we define a [struct](https://move-language.github.io/move/structs-and-resources.html) to represent a `Coin` with a given `value`: + +再看这个文件的下一部分,这里定义了一个具有字段 `value` 的[结构体](./structs-and-resources.html) `Coin`: + +``` +module 0xCAFE::BasicCoin { + struct Coin has key { + value: u64, + } + ... +} +``` + +Looking at the rest of the file, we see a function definition that creates a `Coin` struct and stores it under an account: + +再看文件剩余部分,我们会看到一个函数,它会创建一个 `Coin` 结构体,并将其保存在某个账号(account)下: + +``` +module 0xCAFE::BasicCoin { + struct Coin has key { + value: u64, + } + + public fun mint(account: signer, value: u64) { + move_to(&account, Coin { value }) + } +} +``` + +Let's take a look at this function and what it's saying: +* It takes a [`signer`](https://move-language.github.io/move/signer.html) -- an + unforgeable token that represents control over a particular address, and + a `value` to mint. +* It creates a `Coin` with the given value and stores it under the + `account` using the `move_to` operator. + +Let's make sure it builds! This can be done with the `build` command from within the package folder ([`step_1/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_1/BasicCoin/)): + +让我们来看看这个函数和它的含义: +* 此函数需要一个[`signer`](./signer.html)参数 -- 表示不可伪造的 token 受此特定地址的控制; 和一个需要铸造的数量参数 `value`。 +* 此函数使用给定的参数值铸造一个 `Coin`,然后通过 `move_to` 操作将其保存在(全局存储中)给定的 `account` 账户下。 + +我们需要确保它真的执行,这可以通过在包文件夹([`step_1/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_1/BasicCoin/))下的运行 `build` 命令来完成: + +```bash +move build +``` + +
+ +进阶概念及参考引用 (Advanced concepts and references) + +* You can create an empty Move package by calling: + ```bash + move new + ``` +* Move code can also live a number of other places. More information on the + Move package system can be found in the [Move book](https://move-language.github.io/move/packages.html) +* More information on the `Move.toml` file can be found in the [package section of the Move book](https://move-language.github.io/move/packages.html#movetoml). +* Move also supports the idea of [named addresses](https://move-language.github.io/move/address.html#named-addresses), Named addresses are a way to parametrize Move source code so that you can compile the module using different values for `NamedAddr` to get different bytecode that you can deploy, depending on what address(es) you control. They are used quite frequently, and can be defined in the `Move.toml` file in the `[addresses]` section, e.g., + ``` + [addresses] + SomeNamedAddress = "0xC0FFEE" + ``` + +* 你可以通过以下命令创建一个空的 Move 包(move package): + ```bash + move new + ``` +* Move 代码也可以放在其他很多地方, 更多关于 Move 包系统的信息请参阅[Move book](./packages.html) +* 更多关于 `Move.toml` 文件的信息可以参阅[package section of the Move book](./packages.html#movetoml). +* Move语言也支持命名地址的概念([named addresses](./address.html#named-addresses)), 命名地址是一种参数化 Move 源代码的方法, + 就是如果对 `NamedAddr` 使用的不同赋值编译,编译后会获得部署到你控制地址的不同字节码. 这种用法很常见,一般都将地址变量其定义在 `Move.toml` 文件 + 的 `[addresses]` 部分. 例如: + ``` + [addresses] + SomeNamedAddress = "0xC0FFEE" + ``` + +* [Structures](https://move-language.github.io/move/structs-and-resources.html) in Move can be given different + [abilities](https://move-language.github.io/move/abilities.html) that describe what can be done with that type. There are four different abilities: + - `copy`: Allows values of types with this ability to be copied. + - `drop`: Allows values of types with this ability to be popped/dropped. + - `store`: Allows values of types with this ability to exist inside a struct in global storage. + - `key`: Allows the type to serve as a key for global storage operations. + + So in the `BasicCoin` module we are saying that the `Coin` struct can be used as a key + in global storage and, because it has no other abilities, it cannot be + copied, dropped, or stored as a non-key value in storage. So you can't copy + coins, and you also can't lose coins by accident! +* [Functions](https://move-language.github.io/move/functions.html) are default + private, and can also be `public`, + [`public(friend)`](https://move-language.github.io/move/friends.html), or + `public(script)`. The last of these states that this function can be + called from a transaction script. `public(script)` functions can also be + called by other `public(script)` functions. +* `move_to` is one of the [five different global storage operators](https://move-language.github.io/move/global-storage-operators.html). + +* Move [结构体](./chpater_16_structs-and-resources.html)可以通过给类型设定不同的能力[abilities](./chapter_19_abilities.html)让类型下支持对应的行为. 有四种能力: + - `copy`: 允许此类型的值被复制 + - `drop`: 允许此类型的值被弹出/丢弃 + - `store`: 允许此类型的值存在于全局存储的某个结构体中 + - `key`: 允许此类型作为全局存储中的键(具有 `key` 能力的类型才能保存到全局存储中) + + 所以 `BasicCoin` 模块下的 `Coin` 结构体可以用作全局存储(global storage)的键(key), 因为它又不具备其他能力,它不能 + 被拷贝,不能被丢弃, 也不能作为非key来保存在(全局)存储里. 你无法复制 `Coin`,也不会意外弄丢它. +* 函数[Functions](./functions.html)默认是私有的(private), 也可以声明为 `public` [`public(friend)`](https://move-language.github.io/move/friends.html), `public(script)`. 最后一个声明(指 `public(script)`)的函数可以被事务脚本调用。`public(script)` 函数也可以被其他 `public(script)` 函数调用。(注意:在最新版本的 Move中,`public(script)` 已经被废弃,被`public entry` 取代,下同,译者注) +* `move_to` 是[五种不同的全局存储操作](./global-storage-operators.html)之一 + +
+ +## Step 2: 给模块(Module)添加单元测试 (Adding unit tests to my first Move module) + +Now that we've taken a look at our first Move module, we'll take a look at a test to make sure minting works the way we expect it to by changing directory to [`step_2/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_2/BasicCoin). Unit tests in Move are similar to unit tests in Rust if you're familiar with them -- tests are annotated with `#[test]` and written like normal Move functions. + +You can run the tests with the `move test` command: (原文是 `package test`,应该有误) + +现在我们已经完成了我们的第一个 Move 模块,我们将切换到目录[`step_2/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_2/BasicCoin)下并完成一个测试,确保铸币按我们预期的方式工作。 +如果你熟悉它们(Move 和 Rust)的话,Move 中的单元测试类似于 Rust 中的单元测试 —— 测试代码使用 `#[test]` 注解,并像编写普通的 Move 函数一样。 + +可以通过 `move test` 命令来执行测试: + +```bash +move test +``` + +Let's now take a look at the contents of the [`FirstModule.move`file](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_2/BasicCoin/sources/FirstModule.move). The first new thing you'll +see is this test: + +现在我们来完成文件[`FirstModule.move`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_2/BasicCoin/sources/FirstModule.move)的具体内容,你将看到的第一个新事项是这个测试: + +``` +module 0xCAFE::BasicCoin { + ... + // Declare a unit test. It takes a signer called `account` with an + // address value of `0xC0FFEE`. + #[test(account = @0xC0FFEE)] + fun test_mint_10(account: signer) acquires Coin { + let addr = signer::address_of(&account); + mint(account, 10); + // Make sure there is a `Coin` resource under `addr` with a value of `10`. + // We can access this resource and its value since we are in the + // same module that defined the `Coin` resource. + assert!(borrow_global(addr).value == 10, 0); + } +} +``` + +This is declaring a unit test called `test_mint_10` that mints a `Coin` struct under the `account` with a `value` of `10`. It is then checking that the minted +coin in storage has the value that is expected with the `assert!` call. If the assertion fails the unit test will fail. + +这里声明了一个命名为 `test_mint_10` 的单元测试,它在 `account` 账户地址下铸造了一个包含 `value` 为 `10`的 `Coin`,然后通过 `assert!` 断言检查已经铸造成功并保存在(全局)存储中的 `Coin` 的值是否与期望值一致。如果断言 `assert` 执行失败,则单元测试失败。 + +
+ +进阶概念及参考练习 (Advanced concepts and exercises) + +* There are a number of test-related annotations that are worth exploring, they can be found + [here](https://github.com/move-language/move/blob/main/language/changes/4-unit-testing.md#testing-annotations-their-meaning-and-usage). + You'll see some of these used in Step 5. +* Before running unit tests, you'll always need to add a dependency on the Move + standard library. This can be done by adding an entry to the `[dependencies]` + section of the `Move.toml`, e.g., + + ```toml + [dependencies] + MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "Std" = "0x1" } } + ``` + + Note that you may need to alter the path to point to the `move-stdlib` directory under + `/language`. You can also specify git dependencies. You can read more on Move + package dependencies [here](https://move-language.github.io/move/packages.html#movetoml). + +* 很多测试相关的注解(annotations)都值得仔细探索, 参阅[用法](https://github.com/move-language/move/blob/main/language/changes/4-unit-testing.md#testing-annotations-their-meaning-and-usage)。 在 `Step 5` 中会看到更多用法. + +* 执行测试之前,需要设定Move标准库依赖关系,找到 `Move.toml` 并在 `[dependencies]` 段内进行设定, 例如 + + ```toml + [dependencies] + MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "Std" = "0x1" } } + ``` +注意, 需要修改 `/language` 中的内容来匹配实际 `move-stdlib` 所在的目录路径. 也可以用 `git` 方式指定依赖, 关于 Move 包依赖(package denpendices)信息可参阅[package文档](./packages.html#movetoml) + +#### 练习 (Exercises) + +* Change the assertion to `11` so that the test fails. Find a flag that you can pass to the `move test` command that will show you the global state when the test fails. It should look something like this: + +* 将断言值改为 `11` 将导致断言执行失败, 找一个可以传递给 `move test` 命令的标志,当测试失败时它会显示全局状态。看起来像这样: + ``` + ┌── test_mint_10 ────── + │ error[E11001]: test failure + │ ┌─ ./sources/FirstModule.move:24:9 + │ │ + │ 18 │ fun test_mint_10(account: signer) acquires Coin { + │ │ ------------ In this function in 0xcafe::BasicCoin + │ · + │ 24 │ assert!(borrow_global(addr).value == 11, 0); + │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to abort but it aborted with 0 here + │ + │ + │ ────── Storage state at point of failure ────── + │ 0xc0ffee: + │ => key 0xcafe::BasicCoin::Coin { + │ value: 10 + │ } + │ + └────────────────── + ``` + +* Find a flag that allows you to gather test coverage information, and then play around with using the `move coverage` command to look at coverage statistics and source coverage. + +* 找一个允许您收集测试覆盖率信息的标志,然后使用 `move coverage` 命令查看覆盖率统计信息和源码覆盖率。 + +
+ +## Step 3: 设计 `BasicCoin` 模块(Module) (Designing my `BasicCoin` module) + +In this section, we are going to design a module implementing a basic coin and balance interface, where coins can be minted and transferred between balances held under different addresses. + +在本节中,我们将设计一个具有基本代币和余额(balance)接口功能的模块,通过他们来实现币的挖矿铸造,不同地址之下钱包的转账。 + +The signatures of the public Move function are the following: + +Move 语言的 `public function` 签名如下: + +``` +/// Publish an empty balance resource under `account`'s address. This function must be called before +/// minting or transferring to the account. +public fun publish_balance(account: &signer) { ... } + +/// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner. +public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance { ... } + +/// Returns the balance of `owner`. +public fun balance_of(owner: address): u64 acquires Balance { ... } + +/// Transfers `amount` of tokens from `from` to `to`. +public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { ... } +``` + +Next we look at the data structs we need for this module. + +接下来再看本模块所需要各数据结构. + +A Move module doesn't have its own storage. Instead, Move "global storage" (what we call our +blockchain state) is indexed by addresses. Under each address there are Move modules (code) and Move resources (values). + +Move 语言的模块没有自己的数据存储,相反的是 Move 语言提供按地址(addresses) 索引的 **全局存储** (也是就是我们所说的区块链状态(blockchain state)). +每个地址之下包含有 Move 模块(代码)和 Move 资源 (数据)。 + +The global storage looks roughly like this in Rust syntax: + +在 Rust 语法中,全局存储看起来有点像这样: + +```rust +struct GlobalStorage { + resources: Map> + modules: Map> +} +``` + +The Move resource storage under each address is a map from types to values. (An observant reader might observe that this means each address can only have one value of each type.) This conveniently provides us a native mapping indexed by addresses. +In our `BasicCoin` module, we define the following `Balance` resource representing the number of coins each address holds: + +每个地址下的 Move 资源存储是一个类型到数值的映射。(细心的读者也许已经注意到每个地址, 每个类型下只能对应一个具体值)。这方便地为我们提供了一个按地址索引的本地映射。 +在 `BasicCoin` 模块中,定义了每个 `Balance` (钱包,余额)资源表示每个地址下持有的币的数量: + +``` +/// Struct representing the balance of each address. +struct Balance has key { + coin: Coin // same Coin from Step 1 +} +``` + +Roughly the Move blockchain state should look like this: + +区块链状态(`Move blockchain state`)看起来大致如下: + +![](https://raw.githubusercontent.com/move-language/move/main/language/documentation/tutorial/diagrams/move_state.png) + +#### 进阶主题 (Advanced topics) : + +public(script) functions + +Only functions with `public(script)` visibility can be invoked directly in transactions. So if you would like to call the `transfer` method directly from a transaction, you'll want to change its signature to: + +只有`public(script)`可见行的函数才能直接被交易调用,所以如果你要直接在交易内调用`transfer`方法,那么需要将函数签改成如下格式: + +``` +public(script) fun transfer(from: signer, to: address, amount: u64) acquires Balance { ... } +``` +Read more on Move function visibilities [here](https://move-language.github.io/move/functions.html#visibility). + +关于函数可见性的更多信息,请参阅[Move function visibilities](./functions.html#visibility)。 + + +
+与 Ethereum/Solidity 的比较 (Comparison with Ethereum/Solidity) + +In most Ethereum [ERC-20]((https://ethereum.org/en/developers/docs/standards/tokens/erc-20/)) contracts, the balance of each address is stored in a _state variable_ of type mapping(address => uint256). This state variable is stored in the storage of a particular smart contract. + +在大多数以太坊[ERC-20]((https://ethereum.org/en/developers/docs/standards/tokens/erc-20/))智能合约中,各个账户地址下的余额保存在类型为 mapping(address => uint256)的 __状态变量__ 中,此状态变量存储在具体的智能合约内部存储中。 + +The Ethereum blockchain state might look like this: + +以太坊区块链的状态看起来大致如下: + +![](https://raw.githubusercontent.com/move-language/move/main/language/documentation/tutorial/diagrams/solidity_state.png) +
+ +## Step 4: 实现 `BasicCoin` 模块span id="Step4"> (Implementing my `BasicCoin` module) + +We have created a Move package for you in folder `step_4` called `BasicCoin`. The `sources` folder contains source code for all your Move modules in the package, including `BasicCoin.move`. In this section, we will take a closer look at the implementation of the methods inside [`BasicCoin.move`](https://github.com/move-language/move/blob/main/language/documentation/tutorial/step_4/BasicCoin/sources/BasicCoin.move). + +我们已经在 `step_4` 文件夹上创建了名叫 `BasicCoin` 的 Move 包。`sources` 文件夹包含所有的 Move 包(package)的模块源码,包括 `BasicCoin.move`。 在本节中,我们将仔细研究[`BasicCoin.move`](https://github.com/move-language/move/blob/main/language/documentation/tutorial/step_4/BasicCoin/sources/BasicCoin.move)内部方法的实现。 + +### 编译代码 (Compiling our code) + +Let's first try building the code using Move package by running the following command in [`step_4/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_4/BasicCoin) folder: + +首先尝试在文件夹[`step_4/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_4/BasicCoin)中运行以下命令,使用 Move 包构建代码: + +```bash +move build +``` + +### 方法的实现 (Implementation of methods) + +Now let's take a closer look at the implementation of the methods inside [`BasicCoin.move`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_4/BasicCoin/sources/BasicCoin.move). + +现在仔细看看[`BasicCoin.move`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_4/BasicCoin/sources/BasicCoin.move)中内部方法的实现。 + +
+ +publish_balance方法 (Method publish_balance) + +This method publishes a `Balance` resource to a given address. Since this resource is needed to receive coins through minting or transferring, `publish_balance` method must be called by a user before they can receive money, including the module owner. + +此方法将 `Balance` 资源发布到指定地址名下。由于此资源需要通过铸造或转账来接收代币,必须由用户先调用方法 `publish_balance` 才能接收钱,包括模块所有者。 + +This method uses a `move_to` operation to publish the resource: + +此方法使用 `move_to` 操作来发布资源: + +``` +let empty_coin = Coin { value: 0 }; +move_to(account, Balance { coin: empty_coin }); +``` + +
+
+ +mint方法 (Method mint)) + +Here we require that `mint` must be approved by the module owner. We enforce this using the assert statement: +`mint` method mints coins to a given account. + +`mint` 方法将代币铸造到指定的帐户。在此我们要求 `mint` 必须得到模块所有者的批准。我们使用 `assert` 语句强制执行此操作: + +``` +assert!(signer::address_of(&module_owner) == MODULE_OWNER, errors::requires_address(ENOT_MODULE_OWNER)); +``` + +Assert statements in Move can be used in this way: `assert!(, );`. This means that if the `` is false, then abort the transaction with ``. Here `MODULE_OWNER` and `ENOT_MODULE_OWNER` are both constants defined at the beginning of the module. And `errors` module defines common error categories we can use. +It is important to note that Move is transactional in its execution -- so if an [abort](https://move-language.github.io/move/abort-and-assert.html) is raised no unwinding of state needs to be performed, as no changes from that transaction will be persisted to the blockchain. + +Move 中的 `assert` 语句可以这样使用:`assert!(, );`。这意味着如果 `` 为假,则使用中止错误码 `` 来终止交易。此处的 `MODULE_OWNER` 和 `ENOT_MODULE_OWNER` 都是在模块开头定义的常量。`errors` 模块定义了我们可以使用的常见错误种类。重点是我们需要注意 Move 在其执行过程中是事务性的-- 因此,如果触发[中止(abort)](./chapter_12_abort-and-assert.html),并不用回退已执行状态的,因为该事务的任何更改都不会持久保存到区块链。 + +We then deposit a coin with value `amount` to the balance of `mint_addr`. + +然后将数量为 `amount` 的代币存入 `mint_addr` 的余额中。 + +``` +deposit(mint_addr, Coin { value: amount }); +``` +
+ +
+ +balance_of方法 (Method balance_of) + +We use `borrow_global`, one of the global storage operators, to read from the global storage. + +我们使用全局存储操作之一的 `borrow_global` 从全局存储中读取资源(数据)。 + +``` +borrow_global(owner).coin.value + | | \ / + resource type address field names +``` +
+ +
+ +transfer方法 (Method transfer) + +This function withdraws tokens from `from`'s balance and deposits the tokens into `to`s balance. We take a closer look at `withdraw` helper function: + +该函数从 `from` 的余额中提取代币并将代币存入 `to` 的余额中。我们仔细研究帮助函数 `withdraw`: + +``` +fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } +} +``` + +At the beginning of the method, we assert that the withdrawing account has enough balance. We then use `borrow_global_mut` to get a mutable reference to the global storage, and `&mut` is used to create a [mutable reference](https://move-language.github.io/move/references.html) to a field of a struct. We then modify the balance through this mutable reference and return a new coin with the withdrawn amount. + +在方法开始,我们断言提款账户有足够的余额。然后我们使用 `borrow_global_mut` 来获得全局存储的可变引用,并用 `&mut` 创建结构体字段的[可变引用](./references.html)。然后我们通过这个可变引用修改余额并返回一个带有提取金额的新代币。 + +
+ +### 练习 (Exercises) + +There are two `TODO`s in our module, left as exercises for the reader: +- Finish implementing the `publish_balance` method. +- Implement the `deposit` method. + +在模块中有两个 TODOs,留给读者练习: +- 完成 `publish_balance` 方法的实现。 +- 实现 `deposit` 方法。 + +The solution to this exercise can be found in [`step_4_sol`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_4_sol) folder. + +此练习的解决方案可以在[`step_4_sol`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_4_sol)文件夹中找到。 + +**额外练习** (**Bonus exercise**) + +- What would happen if we deposit too many tokens to a balance? +- 如果我们在余额中存入太多会发生什么? + + +## Step 5: 在模块 `BasicCoin` 中添加和使用单元测试 (Adding and using unit tests with the `BasicCoin` module) + +In this step we're going to take a look at all the different unit tests we've written to cover the code we wrote in step 4. We're also going to take a look at some tools we can use to help us write tests. + +在这一步中,来看看我们为覆盖在 `step 4` 中编写的代码而编写的所有不同的单元测试。还将看看我们可以用来帮助我们编写测试用例的一些工具。 + +To get started, run the `move test` command in the [`step_5/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_5/BasicCoin) folder + +首先,请在文件夹 [`step_5/BasicCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_5/BasicCoin)中 运行 `move test` 命令。 + +```bash +move test +``` +You should see something like this: + +您应该看到如下内容: + +``` +INCLUDING DEPENDENCY MoveStdlib +BUILDING BasicCoin +Running Move unit tests +[ PASS ] 0xcafe::BasicCoin::can_withdraw_amount +[ PASS ] 0xcafe::BasicCoin::init_check_balance +[ PASS ] 0xcafe::BasicCoin::init_non_owner +[ PASS ] 0xcafe::BasicCoin::publish_balance_already_exists +[ PASS ] 0xcafe::BasicCoin::publish_balance_has_zero +[ PASS ] 0xcafe::BasicCoin::withdraw_dne +[ PASS ] 0xcafe::BasicCoin::withdraw_too_much +Test result: OK. Total tests: 7; passed: 7; failed: 0 +``` + +Taking a look at the tests in the [`BasicCoin` module](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_5/BasicCoin/sources/BasicCoin.move) we've tried to keep each unit test to testing one particular behavior. + +看看 [`BasicCoin` ](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_5/BasicCoin/sources/BasicCoin.move)模块中的测试,我们试图让每个单元测试都测试一个具体的行为。 + +
+Exercise (练习) + +After taking a look at the tests, try and write a unit test called `balance_of_dne` in the `BasicCoin` module that tests the case where a `Balance` resource doesn't exist under the address that `balance_of` is being called on. It should only be a couple lines! + +在查看测试之后,尝试在 `BasicCoin` 模块中编写一个单元测试 `balance_of_dne`,测试地址没有 `Balance` 资源的情况,调用 `balance_of` 方法的执行结果。它应该只有几行代码。 + +The solution to this exercise can be found in [`step_5_sol`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_5_sol). + +练习的答案可以在[`step_5_sol`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_5_sol)中找到。 + +
+ +## Step 6: `BasicCoin` 模块泛型化(Making my `BasicCoin` module generic) + +In Move, we can use generics to define functions and structs over different input data types. Generics are a great building block for library code. In this section, we are going to make our simple `BasicCoin` module generic so that it can serve as a library module that can be used by other user modules. + +在 Move 语言中,我们可以使用泛型来定义不同输入数据类型的函数和结构体。泛型是库代码的重要组成部分。在本节中,我们将使我们的简单 `BasicCoin` 模块泛型化,以便它可以用作其他用户模块可以使用的模块库。 + +First, we add type parameters to our data structs: + +首先,我们将类型参数添加到我们的数据结构中: + +``` +struct Coin has store { + value: u64 +} + +struct Balance has key { + coin: Coin +} +``` + +We also add type parameters to our methods in the same manner. For example, `withdraw` becomes the following: + +我们还以相同的方式将类型参数添加到我们的方法中。例如,`withdraw` 变成如下: + +``` +fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } +} +``` + +Take a look at [`step_6/BasicCoin/sources/BasicCoin.move`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_6/BasicCoin/sources/BasicCoin.move) to see the full implementation. + +查看[`step_6/BasicCoin/sources/BasicCoin.move`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_6/BasicCoin/sources/BasicCoin.move)完整的实现。 + +At this point, readers who are familiar with Ethereum might notice that this module serves a similar purpose as the [ERC20 token standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/), which provides an interface for implementing fungible tokens in smart contracts. One key advantage of using generics is the ability to reuse code since the generic library module already provides a standard implementation and the instantiating module can provide customizations by wrapping the standard implementation. + +此时,熟悉以太坊的读者可能会注意到,该模块的用途与[ERC20 token standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/)类似,后者提供了在智能合约中实现可替代代币的接口。使用泛型的一个关键优势是能够重用代码,因为泛型模块库已经提供了标准实现,并且实例化模块可以通过包装标准实现提供定制化功能。 + +We provide a little module called [`MyOddCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_6/BasicCoin/sources/MyOddCoin.move) that instantiates the `Coin` type and customizes its transfer policy: only odd number of coins can be transferred. We also include two [tests](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_6/BasicCoin/sources/MyOddCoin.move) to test this behavior. You can use the commands you learned in step 2 and step 5 to run the tests. + +我们提供了一个称为[`MyOddCoin`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_6/BasicCoin/sources/MyOddCoin.move)并实例化 `Coin` 类型并自定义其转移策略的小模块:只能转移奇数个代币。其还包括两个 [tests](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_6/BasicCoin/sources/MyOddCoin.move)来测试这种行为。您可以使用在第 2 步和第 5 步中学到的命令来运行测试。 + + +#### 进阶主题 (Advanced topics): + +
+ +phantom 类型参数 (phantom type parameters) + +In definitions of both `Coin` and `Balance`, we declare the type parameter `CoinType` to be phantom because `CoinType` is not used in the struct definition or is only used as a phantom type parameter. + +在 `Coin` 和 `Balance `的定义中,我们将类型参数 `CoinType` 声明为phantom,因为 `CoinType` 没有在结构体定义中使用或仅用作 phantom 类型参数。 + +Read more about phantom type parameters here. + +阅读更多有关 [phantom 类型参数](./generics.md#phantom-type-parameters) 信息. + +
+ +## 进阶步骤 (Advanced steps) + +Before moving on to the next steps, let's make sure you have all the prover dependencies installed. + +在继续下一步之前,确保您已安装所有的验证器依赖项。 + +Try running `boogie /version `. If an error message shows up saying "command not found: boogie", you will have to run the setup script and source your profile: + +尝试运行 `boogie /version` 。如果出现错误消息“找不到命令:boogie”,您将必须运行安装脚本并更新环境配置(`source ~/.profile`): + +```bash +# run the following in move repo root directory +./scripts/dev_setup.sh -yp +source ~/.profile +``` + +## Step 7: 使用Move验证器(Use the Move prover) + +Smart contracts deployed on the blockchain may manipulate high-value assets. As a technique that uses strict mathematical methods to describe behavior and reason correctness of computer systems, formal verification has been used in blockchains to prevent bugs in smart contracts. [The Move prover](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/prover-guide.md) is an evolving formal verification tool for smart contracts written in the Move language. The user can specify functional properties of smart contracts using the [Move Specification Language (MSL)](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/spec-lang.md) and then use the prover to automatically check them statically. To illustrate how the prover is used, we have added the following code snippet to the [BasicCoin.move](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_7/BasicCoin/sources/BasicCoin.move): + +部署在区块链上的智能合约可能会操纵高价值资产。作为一种使用严格的数学方式来描述计算机系统的行为和推理正确性的技术,形式化验证已被用于区块链,以防止智能合约中错误的产生。 [Move验证器](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/prover-guide.md)是一种在进化中、用Move 语言编写的智能合约形式化验证工具。用户可以使用[Move语言规范(Move Specification Language (MSL))](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/spec-lang.md)指定智能合约的功能属性,然后使用验证器自动静态检查它们。 +为了说明如何使用验证器,我们在[BasicCoin.move](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_7/BasicCoin/sources/BasicCoin.move)中添加了以下代码片段: + +``` + spec balance_of { + pragma aborts_if_is_strict; + } +``` + +Informally speaking, the block `spec balance_of {...}` contains the property specification of the method `balance_of`. + +通俗地说,代码块 `spec balance_of {...}` 包含 `balance_of` 方法的属性规范说明。 + +Let's first run the prover using the following command inside [`BasicCoin` directory](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_7/BasicCoin/): + +首先在[`BasicCoin` directory](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_7/BasicCoin/)目录中使用以下命令运行验证器。 + +```bash +move prove +``` + +which outputs the following error information: + +它输出以下错误信息: + +``` +error: abort not covered by any of the `aborts_if` clauses + ┌─ ./sources/BasicCoin.move:38:5 + │ +35 │ borrow_global>(owner).coin.value + │ ------------- 由于执行失败这里发生中止 + · +38 │ ╭ spec balance_of { +39 │ │ pragma aborts_if_is_strict; +40 │ │ } + │ ╰─────^ + │ + = at ./sources/BasicCoin.move:34: balance_of + = owner = 0x29 + = at ./sources/BasicCoin.move:35: balance_of + = 中止 + +Error: exiting with verification errors +``` + +The prover basically tells us that we need to explicitly specify the condition under which the function `balance_of` will abort, which is caused by calling the function `borrow_global` when `owner` does not own the resource `Balance`. To remove this error information, we add an `aborts_if` condition as follows: + +验证器大体上告诉我们,我们需要明确指定函数 `balance_of` 中止的条件,中止原因是 `owner`(函数调用者)在没有资源 `Balance` 的情况下调用 `borrow_global` 函数导致的。要去掉此错误信息,我们添加如下 `aborts_if` 条件: + + +``` + spec balance_of { + pragma aborts_if_is_strict; + aborts_if !exists>(owner); + } +``` + +After adding this condition, try running the `prove` command again to confirm that there are no verification errors: + +添加此条件后,再次尝试运行prove命令,确认没有验证错误: + +```bash +move prove +``` + +Apart from the abort condition, we also want to define the functional properties. In Step 8, we will give more detailed introduction to the prover by specifying properties for the methods defined the `BasicCoin` module. + +除了中止条件,我们还想定义功能属性。在第 8 步中,我们将通过为定义 `BasicCoin` 模块的方法指定属性来更详细地介绍验证器。 + + +## 第 8 步:为 `BasicCoin` 模块编写正式规范(Write formal specifications for the `BasicCoin` module) + +
+ + 取款方法 (Method withdraw) + +The signature of the method `withdraw` is given below: + + 取款(`withdraw`) 方法的签名如下: + +``` +fun withdraw(addr: address, amount: u64) : Coin acquires Balance +``` + +The method withdraws tokens with value `amount` from the address `addr` and returns a created Coin of value `amount`. The method `withdraw` aborts when 1) `addr` does not have the resource `Balance` or 2) the number of tokens in `addr` is smaller than `amount`. We can define conditions like this: + +该方法从地址 `addr` 中提取数量为 `amount` 的代币,然后创建数量为 `amount` 的代币并将其返回。当出现如下情况会中止: + 1) 地址 `addr` 没有资源 `Balance`,或 + 2) 地址 `addr` 中的代币数量小于 `amount` 时,`withdraw` 。 + +我们可以这样定义条件: + +``` + spec withdraw { + let balance = global>(addr).coin.value; + aborts_if !exists>(addr); + aborts_if balance < amount; + } +``` + +As we can see here, a spec block can contain let bindings which introduce names for expressions. `global(address): T` is a built-in function that returns the resource value at `addr`. `balance` is the number of tokens owned by `addr`. `exists(address): bool` is a built-in function that returns true if the resource T exists at address. Two `aborts_if` clauses correspond to the two conditions mentioned above. In general, if a function has more than one `aborts_if` condition, those conditions are or-ed with each other. By default, if a user wants to specify aborts conditions, all possible conditions need to be listed. Otherwise, the prover will generate a verification error. However, if `pragma aborts_if_is_partial` is defined in the spec block, the combined aborts condition (the or-ed individual conditions) only *imply* that the function aborts. The reader can refer to the [MSL](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/spec-lang.md) document for more information. + +正如我们在这里看到的,一个 spec 块可以包含 `let` 绑定,它为表达式引入名称。 +`global(address): T` 是一个返回 `addr` 资源值的内置函数。`balance` 是 `addr` 拥有的代币数量。 +`exists(address): bool` 是一个内置函数,如果指定的地址(address)在(全局存储中)有资源 `T` 则返回 `true` 。 +两个 `aborts_if` 子句对应上述两个条件。通常,如果一个函数有多个 `aborts_if` 条件,这些条件之间是相互对等的。默认情况下,如果用户想要指定中止条件,则需要列出所有可能的条件。否则验证器将产生验证错误。 +但是,如果在 `spec` 代码块中定义了 `pragma aborts_if_is_partial`,则组合中止条件(或对等的单个条件)仅 *暗示* 函数中止。 +读者可以参考 [MSL](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/spec-lang.md) 文档了解更多信息。 + +The next step is to define functional properties, which are described in the two `ensures` clauses below. First, by using the `let post` binding, `balance_post` represents the balance of `addr` after the execution, which should be equal to `balance - amount`. Then, the return value (denoted as `result`) should be a coin with value `amount`. + +下一步是定义功能属性,这些属性在下面的两个 `ensures` 子句中进行了描述。首先,通过使用 `let post` 绑定,`balance_post` 表示地址 `addr` 执行后的余额,应该等于 `balance - amount`。那么,返回值(表示为 `result` )应该是一个价值为 `amount` 的代币。 + +``` + spec withdraw { + let balance = global>(addr).coin.value; + aborts_if !exists>(addr); + aborts_if balance < amount; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance - amount; + ensures result == Coin { value: amount }; + } +``` +
+ +
+ + 存款方法 (Method deposit) + +The signature of the method `deposit` is given below: + +存款(`deposit`)方法的签名如下: + +``` +fun deposit(addr: address, check: Coin) acquires Balance +``` + +The method deposits the `check` into `addr`. The specification is defined below: + +该方法将代币 `check` 存入地址 `addr`. 规范定义如下: + +``` + spec deposit { + let balance = global>(addr).coin.value; + let check_value = check.value; + + aborts_if !exists>(addr); + aborts_if balance + check_value > MAX_U64; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance + check_value; + } +``` + +`balance` represents the number of tokens in `addr` before execution and `check_value` represents the number of tokens to be deposited. The method would abort if 1) `addr` does not have the resource `Balance` or 2) the sum of `balance` and `check_value` is greater than the maxium value of the type `u64`. The functional property checks that the balance is correctly updated after the execution. + +`balance` 表示 `addr` 执行前的代币数量,`check_value` 表示要存入的代币数量。方法出现如下情况将会中止: + 1) 地址 `addr` 没有 `Balance` 资源, 或 + 2) `balance` 与 `check_value` 之和大于 `u64` 的最大值。 + +该功能属性检查执行后余额是否正确更新。 + + +
+ +
+ + 转账方法 (Method transfer) + +The signature of the method `transfer` is given below: + +转账(`transfer`)方法的签名如下: + +``` +public fun transfer(from: &signer, to: address, amount: u64, _witness: CoinType) acquires Balance +``` + +The method transfers the `amount` of coin from the account of `from` to the address `to`. The specification is given below: + +该方法将数量为 `amount` 的代币从帐户 `from` 转账给地址 `to`。规范如下: + +``` + spec transfer { + let addr_from = signer::address_of(from); + + let balance_from = global>(addr_from).coin.value; + let balance_to = global>(to).coin.value; + let post balance_from_post = global>(addr_from).coin.value; + let post balance_to_post = global>(to).coin.value; + + ensures balance_from_post == balance_from - amount; + ensures balance_to_post == balance_to + amount; + } +``` + +`addr_from` is the address of `from`. Then the balances of `addr_from` and `to` before and after the execution are obtained. +The `ensures` clauses specify that the `amount` number of tokens is deducted from `addr_from` and added to `to`. However, the prover will generate the error information as below: + +`addr_from` 是账户 `from` 的地址,然后获取执行前两个地址 `addr_from` 和 `to` 的余额。 + `ensures` 子句指定从 `addr_from` 减去 `amount` 数量的代币,添加到 `to`。然而,验证器会生成以下错误: + +``` +error: post-condition does not hold + ┌─ ./sources/BasicCoin.move:57:9 + │ +62 │ ensures balance_from_post == balance_from - amount; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ + ... +``` + +The property is not held when `addr_from` is equal to `to`. As a result, we could add an assertion `assert!(from_addr != to)` in the method to make sure that `addr_from` is not equal to `to`. + +当 `addr_from` 等于 `to` 时,这个属性无效。因此,我们可以在方法中添加一个断言,`assert!(from_addr != to)` 来确保 `addr_from` 不等于 `to`。 + +
+ + +
+ + 练习 (Exercises) + +- Implement the `aborts_if` conditions for the `transfer` method. +- 为` transfer` 方法实现 `aborts_if` 条件。 +- Implement the specification for the `mint` and `publish_balance` method. +- 为 `mint` 和 `publish_balance` 方法实现规范。 + +The solution to this exercise can be found in [`step_8_sol`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_8_sol). + +练习的解答可以在 [`step_8_sol`](https://github.com/move-language/move/tree/main/language/documentation/tutorial/step_8_sol)中找到。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/overview.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/overview.md new file mode 100644 index 000000000..d08bf4352 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/overview.md @@ -0,0 +1,200 @@ +--- +id: overview +title: Overview +sidebar_label: Move +--- + +Move is a next generation language for secure, sandboxed, and formally verified programming. Its first use case is for the Diem blockchain, where Move provides the foundation for its implementation. However, Move has been developed with use cases in mind outside a blockchain context as well. + +### Start Here + + + + + + + +### Primitive Types + + + + + + + + + + + +### Basic Concepts + + + + + + + + + + + + + + +### Global Storage + + + + + + +### Reference + + + + + diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/packages.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/packages.md new file mode 100644 index 000000000..4ab185d12 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/packages.md @@ -0,0 +1,348 @@ +# 程序包(packages) + +Packages allow Move programmers to more easily re-use code and share it +across projects. The Move package system allows programmers to easily: +* Define a package containing Move code; +* Parameterize a package by [named addresses](./address.md); +* Import and use packages in other Move code and instantiate named addresses; +* Build packages and generate associated compilation artifacts from packages; and +* Work with a common interface around compiled Move artifacts. + +包允许 `Move` 程序员更轻松地重用代码并在项目之间共享。`Move` 包系统允许程序员轻松地: +* 定义一个包含 `Move`代码的包; +* 通过命名地址参数化包; +* 在其他 `Move` 代码中导入和使用包并实例化命名地址; +* 构建包并从包中生成相关的编译源代码; +* 使用围绕已编译 `Move` 工件的通用接口。 + +## 包布局和清单语法(Package Layout and Manifest Syntax) + +A Move package source directory contains a `Move.toml` package manifest +file along with a set of subdirectories: + +`Move` 包源目录包含一个`Move.toml`包清单文件以及一组子目录: + +``` + a_move_package + ├── Move.toml (required)(需要的) + ├── sources (required)(需要的) + ├── examples (optional, test & dev mode)(可选的,测试 & 开发者模式) + ├── scripts (optional)(可选的) + ├── doc_templates (optional)(可选的) + └── tests (optional, test mode)(可选的,测试模式) +``` + +The directories marked `required` _must_ be present in order for the directory +to be considered a Move package and to be compiled. Optional directories can +be present, and if so will be included in the compilation process. Depending on +the mode that the package is built with (`test` or `dev`), the `tests` and +`examples` directories will be included as well. + +标记为`required` 的目录必须存在才可以将该目录作为 `Move` 包并进行编译。可选目录被视为可存在的,如果存在,将包含在编译过程里。根据使用 (`test`或`dev`)构建包的模式,`tests`和`examples` 目录也将包含在内。 + +The `sources` directory can contain both Move modules and Move scripts (both +transaction scripts and modules containing script functions). The `examples` +directory can hold additional code to be used only for development and/or +tutorial purposes that will not be included when compiled outside `test` or +`dev` mode. + +`sources`目录可以包含 `Move` 模块和 `Move` 脚本(事务脚本和包含脚本函数的模块)。`Example`目录可以保留仅用于开发和/或用作教程目的附加代码,当在 `test` 或者`dev`模式之外时,这些附加代码编译时不会被包括进来。 + +A `scripts` directory is supported so transaction scripts can be separated +from modules if that is desired by the package author. The `scripts` +directory will always be included for compilation if it is present. +Documentation will be built using any documentation templates present in +the `doc_templates` directory. + +`scripts`目录是被支持的,如果包作者需要,事物脚本可以从模块中分离。如果该`scripts`目录存在,则编译时将始终包含该目录。 +Move将使用存在于`doc_templates` 目录的任何模板构建文档。 + + +### 包清单 Move.toml + +The Move package manifest is defined within the `Move.toml` file and has the +following syntax. Optional fields are marked with `*`, `+` denotes +one or more elements: + +Move 包清单在`Move.toml`文件中定义,并具有以下语法。可选字段标有`*`,`+`表示一个或多个元素: +``` + [package] + name = # e.g., "MoveStdlib" + version = ".." # e.g., "0.1.1" + license* = # e.g., "MIT", "GPL", "Apache 2.0" + authors* = [] # e.g., ["Joe Smith (joesmith@noemail.com)", "Jane Smith (janesmith@noemail.com)"] + + [addresses] # (Optional section) Declares named addresses in this package and instantiates named addresses in the package graph + # One or more lines declaring named addresses in the following format + = "_" | "" # e.g., std = "_" or my_addr = "0xC0FFEECAFE" + + [dependencies] # (Optional section) Paths to dependencies and instantiations or renamings of named addresses from each dependency + # One or more lines declaring dependencies in the following format + = { local = , addr_subst* = { ( = ( | ""))+ } } # local dependencies + = { git = , subdir=, rev=, addr_subst* = { ( = ( | ""))+ } } # git dependencies + + [dev-addresses] # (Optional section) Same as [addresses] section, but only included in "dev" and "test" modes + # One or more lines declaring dev named addresses in the following format + = "_" | "" # e.g., std = "_" or my_addr = "0xC0FFEECAFE" + + [dev-dependencies] # (Optional section) Same as [dependencies] section, but only included in "dev" and "test" modes + # One or more lines declaring dev dependencies in the following format + = { local = , addr_subst* = { ( = ( |
))+ } } +``` +An example of a minimal package manifest with one local dependency and one git dependency: + +一个具有局部依赖项和一个 git 依赖项的最小包清单示例: +``` + [package] + name = "AName" + version = "0.0.0" +``` + +An example of a more standard package manifest that also includes the Move +standard library and instantiates the named address `Std` from it with the +address value `0x1`: + +一个包括 Move 标准库并从中使用地址值`0x1`实例化命名地址`Std`的更标准的包清单示例: + +``` + [package] + name = "AName" + version = "0.0.0" + license = "Apache 2.0" + + [addresses] + address_to_be_filled_in = "_" + specified_address = "0xB0B" + + [dependencies] + # Local dependency + LocalDep = { local = "projects/move-awesomeness", addr_subst = { "std" = "0x1" } } + # Git dependency + MoveStdlib = { git = "https://github.com/diem/diem.git", subdir="language/move-stdlib", rev = "56ab033cc403b489e891424a629e76f643d4fb6b" } + + [dev-addresses] # For use when developing this module + address_to_be_filled_in = "0x101010101" + ``` + +Most of the sections in the package manifest are self explanatory, but named +addresses can be a bit difficult to understand so it's worth examining them in +a bit more detail. + +包清单中的大部分段落都是不言自明的,但命名地址可能有点难以理解,因此值得更详细地检查它们。 + +## 编译期间的命名地址(Named Addresses During Compilation) + +Recall that Move has [named addresses](./address.md) and that +named addresses cannot be declared in Move. Because of this, until now +named addresses and their values needed to be passed to the compiler on the +command line. With the Move package system this is no longer needed, and +you can declare named addresses in the package, instantiate other named +addresses in scope, and rename named addresses from other packages within +the Move package system manifest file. Let's go through each of these +individually: + +回想一下,Move 具有命名地址,并且不能在 Move 中声明命名地址。正因为如此,到目前为止,命名地址及其值都需要在命令行上传递给编译器。但使用 Move 包系统时这将不再需要,您可以在包中声明命名地址,实例化范围内的其他命名地址,并从 Move 包系统清单文件中的其他包重命名命名地址,让我们分别来看看这些: + +### 声明(Declaration) +Let's say we have a Move module in `example_pkg/sources/A.move` as follows: + +假设我们有一个Move模块,`example_pkg/sources/A.move`如下所示: + +```move + module named_addr::A { + public fun x(): address { @named_addr } + } +``` + +We could in `example_pkg/Move.toml` declare the named address `named_addr` in +two different ways. The first: + +我们可以用两种不同`example_pkg/Move.toml`的方式声明命名地址`named_addr`。首先: + +``` + [package] + name = "ExamplePkg" + ... + [addresses] + named_addr = "_" +``` + +Declares `named_addr` as a named address in the package `ExamplePkg` and +that _this address can be any valid address value_. Therefore an importing +package can pick the value of the named address `named_addr` to be any address +it wishes. Intuitively you can think of this as parameterizing the package +`ExamplePkg` by the named address `named_addr`, and the package can then be +instantiated later on by an importing package. + +声明`named_addr`为包`ExamplePkg`中的命名地址,并且 _该地址可以是任何有效的地址值_。因此,导入包可以选择命名地址的值作为`named_addr`它希望的任何地址。直观地,您可以将其视为通过命名地址`named_addr`参数化包 `ExamplePkg`,然后稍后通过导入包使包被实例化。 + +`named_addr` can also be declared as: + +`named_addr`也可以声明为: + +``` + [package] + name = "ExamplePkg" + ... + [addresses] + named_addr = "0xCAFE" +``` + +which states that the named address `named_addr` is exactly `0xCAFE` and cannot be +changed. This is useful so other importing packages can use this named +address without needing to worry about the exact value assigned to it. + +这表明命名的地址`named_addr`是准确的`0xCAFE`并且不能更改。这很有用,因此其他导入包可以使用这个命名地址,而无需担心分配给它的确切值。 + +With these two different declaration methods, there are two ways that +information about named addresses can flow in the package graph: +* The former ("unassigned named addresses") allows named address values to flow + from the importation site to the declaration site. +* The latter ("assigned named addresses") allows named address values to flow + from the declaration site upwards in the package graph to usage sites. + +使用这两种不同的声明方法,有关命名地址的信息可以通过两种方式在包图中流动: +* 前者(“未分配的命名地址”)允许命名地址值从进口站点流向申报站点。 +* 后者(“分配的命名地址”)允许命名地址值从包图中的声明站点向上流动到使用站点。 + +With these two methods for flowing named address information throughout the +package graph the rules around scoping and renaming become important to +understand. + +通过这两种在整个包图中流动命名地址信息的方法,了解范围和重命名的规则变得很重要。 + +## 命名地址的作用域和重命名(Scoping and Renaming of Named Addresses) + +A named address `N` in a package `P` is in scope if: +1. It declares a named address `N`; or +2. A package in one of `P`'s transitive dependencies declares the named address + `N` and there is a dependency path in the package graph between between `P` and the + declaring package of `N` with no renaming of `N`. + +在包`P`中的命名地址`N`如果满足以下条件,则在作用域内: + + 1. 它声明了一个命名地址`N`;或者 + 2. `P`的传递依赖项之一中的包声明了命名地址`N`,并且封装图在`P`和没有重命名的声明包`N`之间有一个依赖路径。 + + Additionally, every named address in a package is exported. Because of this and +the above scoping rules each package can be viewed as coming with a set of +named addresses that will be brought into scope when the package is imported, +e.g., if the `ExamplePkg` package was imported, that importation would bring +into scope the `named_addr` named address. Because of this, if `P` imports two +packages `P1` and `P2` both of which declare a named address `N` an issue +arises in `P`: which "`N`" is meant when `N` is referred to in `P`? The one +from `P1` or `P2`? To prevent this ambiguity around which package a named +address is coming from, we enforce that the sets of scopes introduced by all +dependencies in a package are disjoint, and provide a way to _rename named +addresses_ when the package that brings them into scope is imported. + + 此外,包中的每个命名地址都会被导出。由于这个和上面的范围规则,每个包都可以被视为带有一组命名地址,当包被导入时,这些地址将被带入作用域,例如,如果包`ExamplePkg`被导入,则该导入会将命名地址`named_addr`带入作用域。 因此,如果`P`导入两个包`P1`并且`P2`都声明了一个命名地址`N`,在`P`中则会出现以下问题:当`N`被引用于`P`时我们指的是哪个`N`?来自`P1`或来自`P2`的`N`? 为了防止命名地址来自哪个包的这种歧义,我们强制一个包中所有依赖项引入的范围集是不相交的,并提供一种在将命名地址带入范围的包被导入时重命名命名地址的方法。 + +Renaming a named address when importing can be done as follows in our `P`, +`P1`, and `P2` example above: + +导入时重命名一个命名地址可以在我们的`P`,`P1`和`P2`上面的示例中完成: +``` + [package] + name = "P" + ... + [dependencies] + P1 = { local = "some_path_to_P1", addr_subst = { "P1N" = "N" } } + P2 = { local = "some_path_to_P2" } +``` +With this renaming `N` refers to the `N` from `P2` and `P1N` will refer to `N` +coming from `P1`: + +这种重命名`N`指的是`P2`中的`N`并且`P1N`将指 `P1`中的`N`: +``` + module N::A { + public fun x(): address { @P1N } + } +``` +It is important to note that _renaming is not local_: once a named address `N` +has been renamed to `N2` in a package `P` all packages that import `P` will not +see `N` but only `N2` unless `N` is reintroduced from outside of `P`. This is +why rule (2) in the scoping rules at the start of this section specifies a +"dependency path in the package graph between between `P` and the declaring +package of `N` with no renaming of `N`." + +重要的是要注意 _重命名不是局部的_:一旦一个命名地址`N`在一个包`P`中被重命名为`N2`,所有导入`P`的包都不会看到`N`但只会看到`N2`,除非`N`是从`P`外引入的。这就是为什么本节开头的范围规则中的规则 (2) 特别说明了“在`P`和没有重命名的声明包`N` 的封装图中的依赖路径” 。 + +### 实例化(Instantiation) + +Named addresses can be instantiated multiple times across the package graph as +long as it is always with the same value. It is an error if the same named +address (regardless of renaming) is instantiated with differing values across +the package graph. + +只要命名地址始终具有相同的值,就可以在封装图中多次实例化命名地址。如果在整个封装图中使用不同的值实例化相同的命名地址(无论是否重命名),则会出现错误。 + +A Move package can only be compiled if all named addresses resolve to a value. +This presents issues if the package wishes to expose an uninstantiated named +address. This is what the `[dev-addresses]` section solves. This section can +set values for named addresses, but cannot introduce any named addresses. +Additionally, only the `[dev-addresses]` in the root package are included in +`dev` mode. For example a root package with the following manifest would not compile +outside of `dev` mode since `named_addr` would be uninstantiated: + +只有当所有命名地址都解析为一个值时,才能编译 Move 包。如果包希望公开未实例化的命名地址,则会出现问题。这就是`[dev-addresses]`段要解决的问题。此段可以设置命名地址的值,但不能引入任何命名地址。此外, `dev`模式下仅根包中的`[dev-addresses]`会被包括进来。例如,具有以下清单的根包将不会在`dev`模式之外编译,因为`named_addr`不会被实例化: +``` +[package] +name = "ExamplePkg" +... +[addresses] +named_addr = "_" + +[dev-addresses] +named_addr = "0xC0FFEE" +``` +## 用法、源代码和数据结构( Usage, Artifacts, and Data Structures) + +The Move package system comes with a command line option as part of the Move +CLI `move `. Unless a +particular path is provided, all package commands will run in the current working +directory. The full list of commands and flags for the Move CLI can be found by +running `move --help`. + +Move 软件包系统带有一个命令行选项,作为 Move CLI 的一部分move ` ` ``。除非提供特定路径,否则所有包命令都将在当前工作目录中运行。可以通过运行`move --help`找到 Move CLI 的命令和标志的完整列表。 + +### 用法(Usage) + +A package can be compiled either through the Move CLI commands, or as a library +command in Rust with the function `compile_package`. This will create a +`CompiledPackage` that holds the compiled bytecode along with other compilation +artifacts (source maps, documentation, ABIs) in memory. This `CompiledPackage` +can be converted to an `OnDiskPackage` and vice versa -- the latter being the data of +the `CompiledPackage` laid out in the file system in the following format: + +一个包可以通过 Move CLI 命令,或是当作Rust函数`compile_package`的库命令来编译。 这种编译方法将创建一个编译包`CompiledPackage` 保存已编译的字节码以及其他编译内存中的源代码(源映射、文档、ABIs)。这个`CompiledPackage`可以转换为`OnDiskPackage`,反之亦然——后者是文件系统中的编译包 `CompiledPackage`数据,它的格式如下: + +``` +a_move_package +├── Move.toml +... +└── build + ├── + │ ├── BuildInfo.yaml + │ ├── bytecode_modules + │ │ └── *.mv + │ ├── source_maps + │ │ └── *.mvsm + │ ├── bytecode_scripts + │ │ └── *.mv + │ ├── abis + │ │ ├── *.abi + │ │ └── /*.abi + │ └── sources + │ └── *.move + ... + └── + ├── BuildInfo.yaml + ... + └── sources +``` + +See the `move-package` crate for more information on these data structures and +how to use the Move package system as a Rust library. + +有关这些数据结构和如何将 Move 包系统用作 Rust 库的更多信息,请参阅 `move-package` 箱(crate) 。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/references.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/references.md new file mode 100644 index 000000000..2a23f0cb2 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/references.md @@ -0,0 +1,289 @@ +# 引用(references) + +Move has two types of references: immutable `&` and mutable `&mut`. Immutable references are read +only, and cannot modify the underlying value (or any of its fields). Mutable references allow for +modifications via a write through that reference. Move's type system enforces an ownership +discipline that prevents reference errors. + +Move 支持两种类型的引用:不可变引用 `&` 和可变引用 `&mut`。不可变引用是只读的,不能修改相关值(或其任何字段)。可变引用通过写入该引用进行修改。Move的类型系统强制执行所有权规则,以避免引用错误。 + +For more details on the rules of references, see [Structs and Resources](./structs-and-resources.md) + +更多有关引用规则的详细信息,请参阅:[结构和资源](./structs-and-resources.html). + +## 引用运算符 (Reference Operators) + +Move provides operators for creating and extending references as well as converting a mutable +reference to an immutable one. Here and elsewhere, we use the notation `e: T` for "expression `e` +has type `T`". + +Move 提供了用于创建和扩展引用以及将可变引用转换为不可变引用的运算符。在这里和其他地方,我们使用符号 `e: T` 来表示“表达式 `e` 的类型是 `T` ” + +| Syntax | Type | Description | +| ----------- | ----------------------------------------------------- | -------------------------------------------------------------- | +| `&e` | `&T` where `e: T` and `T` is a non-reference type | Create an immutable reference to `e` | +| `&mut e` | `&mut T` where `e: T` and `T` is a non-reference type | Create a mutable reference to `e`. | +| `&e.f` | `&T` where `e.f: T` | Create an immutable reference to field `f` of struct `e`. | +| `&mut e.f` | `&mut T` where `e.f: T` | Create a mutable reference to field `f` of struct`e`. | +| `freeze(e)` | `&T` where `e: &mut T` | Convert the mutable reference `e` into an immutable reference. | + +| 语法 | 类型 | 描述 | +| ------ | ------ |------ | +| `&e` | `&T` 其中 `e: T` 和 `T` 是非引用类型 | 创建一个不可变的引用 `e` +| `&mut e` | `&mut T` 其中 `e: T` 和 `T` 是非引用类型 | 创建一个可变的引用 `e` +| `&e.f` | `&T` 其中 `e.f: T` | 创建结构 `e` 的字段 `f` 的不可变引用 +| `&mut e.f` | `&mut T` 其中`e.f: T` | 创建结构 `e` 的字段 `f` 的可变引用 +| `freeze(e)` | `&T` 其中`e: &mut T` | 将可变引用 `e` 转换为不可变引用 + +The `&e.f` and `&mut e.f` operators can be used both to create a new reference into a struct or to extend an existing reference: + +`&e.f`和`&mut e.f`运算符既可以用于在结构中创建新引用,也可以用于扩展现有引用: + +```move +let s = S { f: 10 }; +let f_ref1: &u64 = &s.f; // works +let s_ref: &S = &s; +let f_ref2: &u64 = &s_ref.f // also works +``` + +A reference expression with multiple fields works as long as both structs are in the same module: + +只要两个结构都在同一个模块中,具有多个字段的引用表达式就可以工作: + +```move +struct A { b: B } +struct B { c : u64 } +fun f(a: &A): &u64 { + &a.b.c +} +``` + +Finally, note that references to references are not allowed: + +最后,请注意,不允许引用"引用"(Move不支持多重引用, 但Rust可以,译者注): + +```move +let x = 7; +let y: &u64 = &x; +let z: &&u64 = &y; // will not compile +``` + +## 通过引用读取和写入 + +Both mutable and immutable references can be read to produce a copy of the referenced value. + +Only mutable references can be written. A write `*x = v` discards the value previously stored in `x` +and updates it with `v`. + +可以读取可变和不可变引用以生成引用值的副本。 + +只能写入可变引用。写入表达式 `*x = v` 会丢弃先前存储在x中的值,并用 `v` 更新。 + +Both operations use the C-like `*` syntax. However, note that a read is an expression, whereas a +write is a mutation that must occur on the left hand side of an equals. + +两种操作都使用类 C `*` 语法。但是请注意,读取是一个表达式,而写入是一个必须发生在等号左侧的改动。 + +| Syntax | Type | Description | +| ---------- | ----------------------------------- | ----------------------------------- | +| `*e` | `T` where `e` is `&T` or `&mut T` | Read the value pointed to by `e` | +| `*e1 = e2` | `()` where `e1: &mut T` and `e2: T` | Update the value in `e1` with `e2`. | + +| 语法 | 类型 | 描述 | +| ------ | ------ |------ | +| `*e` | `T` 其中 `e` 为 `&T` 或 `&mut T` | 读取 `e` 所指向的值 +| `*e1 = e2` | () 其中 `e1: &mut T` 和 `e2: T` | 用 `e2` 更新 `e1` 中的值 + +In order for a reference to be read, the underlying type must have the +[`copy` ability](./abilities.md) as reading the reference creates a new copy of the value. This rule +prevents the copying of resource values: + +为了读取引用,相关类型必须具备[`copy` 能力](./abilities.html),因为读取引用会创建值的新副本。此规则防止复制资源值: + +```move= +fun copy_resource_via_ref_bad(c: Coin) { + let c_ref = &c; + let counterfeit: Coin = *c_ref; // not allowed! + pay(c); + pay(counterfeit); +} +``` + +Dually: in order for a reference to be written to, the underlying type must have the +[`drop` ability](./abilities.md) as writing to the reference will discard (or "drop") the old value. +This rule prevents the destruction of resource values: + +双重性:为了写入引用,相关类型必须具备[`drop` 能力](./abilities.html),因为写入引用将丢弃(或“删除”)旧值。此规则可防止破坏资源值: + +```move= +fun destroy_resource_via_ref_bad(ten_coins: Coin, c: Coin) { + let ref = &mut ten_coins; + *ref = c; // not allowed--would destroy 10 coins! +} +``` + +## `freeze` 推断 (`freeze` inference) + +A mutable reference can be used in a context where an immutable reference is expected: + +可变引用可以在预期不可变引用的上下文中使用: + +```move +let x = 7; +let y: &mut u64 = &mut x; +``` + +This works because the under the hood, the compiler inserts `freeze` instructions where they are +needed. Here are a few more examples of `freeze` inference in action: + +这是因为编译器会在底层需要的地方插入 `freeze` 指令。以下是更多 `freeze` 实际推断行为的示例: + +```move= +fun takes_immut_returns_immut(x: &u64): &u64 { x } + +// freeze inference on return value +fun takes_mut_returns_immut(x: &mut u64): &u64 { x } + +fun expression_examples() { + let x = 0; + let y = 0; + takes_immut_returns_immut(&x); // no inference + takes_immut_returns_immut(&mut x); // inferred freeze(&mut x) + takes_mut_returns_immut(&mut x); // no inference + + assert!(&x == &mut y, 42); // inferred freeze(&mut y) +} + +fun assignment_examples() { + let x = 0; + let y = 0; + let imm_ref: &u64 = &x; + + imm_ref = &x; // no inference + imm_ref = &mut y; // inferred freeze(&mut y) +} +``` + +### 子类型化 (Subtyping) + +With this `freeze` inference, the Move type checker can view `&mut T` as a subtype of `&T`. As shown +above, this means that anywhere for any expression where a `&T` value is used, a `&mut T` value can +also be used. This terminology is used in error messages to concisely indicate that a `&mut T` was +needed where a `&T` was supplied. For example + +通过freeze推断,Move 类型检查器可以将 `&mut T` 视为 `&T` 的子类型。 如上所示,这意味着对于使用 `&T` 值的任何表达式,也可以使用 `&mut T` 值。此术语用于错误消息中,以简明扼要地表明在提供 `&T` 的地方需要 `&mut T` 。例如: + +```move= +address 0x42 { + module example { + fun read_and_assign(store: &mut u64, new_value: &u64) { + *store = *new_value + } + + fun subtype_examples() { + let x: &u64 = &0; + let y: &mut u64 = &mut 1; + + x = &mut 1; // valid + y = &2; // invalid! + + read_and_assign(y, x); // valid + read_and_assign(x, y); // invalid! + } + } +} +``` + +will yield the following error messages + +将产生以下错误消息 + +```text +error: + ┌── example.move:12:9 ─── + │ + 12 │ y = &2; // invalid! + │ ^ Invalid assignment to local 'y' + · + 12 │ y = &2; // invalid! + │ -- The type: '&{integer}' + · + 9 │ let y: &mut u64 = &mut 1; + │ -------- Is not a subtype of: '&mut u64' + │ + +error: + ┌── example.move:15:9 ─── + │ + 15 │ read_and_assign(x, y); // invalid! + │ ^^^^^^^^^^^^^^^^^^^^^ Invalid call of '0x42::example::read_and_assign'. Invalid argument for parameter 'store' + · + 8 │ let x: &u64 = &0; + │ ---- The type: '&u64' + · + 3 │ fun read_and_assign(store: &mut u64, new_value: &u64) { + │ -------- Is not a subtype of: '&mut u64' + │ +``` + +The only other types currently that has subtyping are [tuples](./tuples.md) + +当前唯一具有子类型的其他类型是[tuple(元组)](./tuples.html) + +## 所有权 (Ownership) + +Both mutable and immutable references can always be copied and extended _even if there are existing +copies or extensions of the same reference_: + +_即使同一引用存在现有副本或扩展_,可变引用和不可变引用始终可以被复制和扩展: + +```move +fun reference_copies(s: &mut S) { + let s_copy1 = s; // ok + let s_extension = &mut s.f; // also ok + let s_copy2 = s; // still ok + ... +} +``` + +This might be surprising for programmers familiar with Rust's ownership system, which would reject +the code above. Move's type system is more permissive in its treatment of +[copies](./variables.md#move-and-copy), but equally strict in ensuring unique ownership of mutable +references before writes. + +对于熟悉 Rust 所有权系统的程序员来说,这可能会令人惊讶,因为他们会拒绝上面的代码。Move 的类型系统在处理[副本](./variables.html#move-and-copy)方面更加宽松 ,但在写入前确保可变引用的唯一所有权方面同样严格。 + +### 无法存储引用 (References Cannot Be Stored) + +References and tuples are the _only_ types that cannot be stored as a field value of structs, which +also means that they cannot exist in global storage. All references created during program execution +will be destroyed when a Move program terminates; they are entirely ephemeral. This invariant is +also true for values of types without the `store` [ability](./abilities.md), but note that +references and tuples go a step further by never being allowed in structs in the first place. + +This is another difference between Move and Rust, which allows references to be stored inside of +structs. + +引用和元组是唯一不能存储为结构的字段值的类型,这也意味着它们不能存在于全局存储中。当 Move 程序终止时,程序执行期间创建的所有引用都将被销毁;它们完全是短暂的。这种不变式也适用于没有[`store` 能力](./chatper_19_abilities.html)的类型的值,但请注意,引用和元组更进一步,从一开始就不允许出现在结构中。 + +这是 Move 和 Rust 之间的另一个区别,后者允许将引用存储在结构内。 + +Currently, Move cannot support this because references cannot be +[serialized](https://en.wikipedia.org/wiki/Serialization), but _every Move value must be +serializable_. This requirement comes from Move's +[persistent global storage](./global-storage-structure.md), which needs to serialize values to +persist them across program executions. Structs can be written to global storage, and thus they must +be serializable. + +One could imagine a fancier, more expressive, type system that would allow references to be stored +in structs _and_ ban those structs from existing in global storage. We could perhaps allow +references inside of structs that do not have the `store` [ability](./abilities.md), but that would +not completely solve the problem: Move has a fairly complex system for tracking static reference +safety, and this aspect of the type system would also have to be extended to support storing +references inside of structs. In short, Move's type system (particularly the aspects around +reference safety) would have to expand to support stored references. But it is something we are +keeping an eye on as the language evolves. + +目前,Move 无法支持这一点,因为引用无法被[序列化](https://en.wikipedia.org/wiki/Serialization),但 _每个 Move 值都必须是可序列化的_。这个要求来自于 Move 的 [持久化全局存储](./global-storage-structure.html),它需要在程序执行期间序列化值以持久化它们。结构体可以写入全局存储,因此它们必须是可序列化的。 + +可以想象一种更奇特、更有表现力的类型系统,它允许将引用存储在结构中,并禁止这些结构存在于全局存储中。我们也许可以允许在没有[`store` 能力](./abilities.html)的结构内部使用引用,但这并不能完全解决问题:Move 有一个相当复杂的系统来跟踪静态引用安全性,并且类型系统的这一方面也必须扩展以支持在结构内部存储引用。简而言之,Move 的类型系统(尤其是与引用安全相关的方面)需要扩展以支持存储的引用。随着语言的发展,我们正在关注这一点。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/signer.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/signer.md new file mode 100644 index 000000000..2bba515c0 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/signer.md @@ -0,0 +1,60 @@ +# 签名者 + +`签名者(signer)`是 Move 内置的资源类型。`签名者(signer)`是一种允许持有者代表特定`地址(address)`行使权力的[能力(capability)](https://en.wikipedia.org/wiki/Object-capability_model)。你可以将原生实现(native implementation)视为: + +```move +struct signer has drop { a: address } +``` + +`signer` 有点像 Unix [UID](https://en.wikipedia.org/wiki/User_identifier),因为它表示一个通过 Move *之外*的代码(例如,通过检查加密签名或密码)进行身份验证的用户。 + +## 与 `address` 的比较 + +Move 程序可以使用地址字面量(literal)创建任何`地址(address)`值,而无需特殊许可: + +```move +let a1 = @0x1; +let a2 = @0x2; +// ... 等等,所有其他可能的地址 +``` + +但是,`signer` 值是特殊的,因为它们不能通过字面量或者指令创建 —— 只能通过 Move 虚拟机(VM)创建。在虚拟机运行带有 `signer` 类型参数的脚本之前,它会自动创建 `signer` 值并将它们传递给脚本: + +```move +script { + use std::signer; + fun main(s: signer) { + assert!(signer::address_of(&s) == @0x42, 0); + } +} +``` + +如果脚本是从 `0x42` 以外的任何地址发送的,则此脚本将中止并返回代码 `0`。 + +交易脚本可以有任意数量的 `signer`,只要 `signer` 参数排在其他参数前面。换句话说,所有 `signer` 参数都必须放在第一位。 + +```move +script { + use std::signer; + fun main(s1: signer, s2: signer, x: u64, y: u8) { + // ... + } +} +``` + +这对于实现具有多方权限原子行为的*多重签名脚本(multi-signer scripts)*很有用。例如,上述脚本的扩展可以在 `s1` 和 `s2` 之间执行原子货币交换。 + +## `signer` 操作符 + +`std::signer` 标准库模块为 `signer` 提供了两个实用函数: + +| 函数 | 描述 | +| ------------------------------------------- | ------------------------------------------------------------- | +| `signer::address_of(&signer): address` | 返回由 `&signer` 包装的地址值。 | +| `signer::borrow_address(&signer): &address` | 返回由 `&signer` 包装的地址的引用。 | + +此外,`move_to(&signer, T)` [全局存储](./global-storage-operators.md)操作符需要一个 `&signer` 参数在 `signer.address` 的帐户下发布资源 `T`。这确保了只有经过身份验证的用户才能在其地址下发布资源。 + +## 所有权 + +与简单的标量值不同,`signer` 值是不可复制的,这意味着他们不能被复制(通过任何操作,无论是通过显式 [`copy`](./variables.md#移动和复制)指令还是通过[解引用(dereference)`*`](./references.md#通过引用读取和写入))。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/standard-library.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/standard-library.md new file mode 100644 index 000000000..85c8d9f43 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/standard-library.md @@ -0,0 +1,695 @@ +# 标准库(Standard Library) + +The Move standard library exposes interfaces that implement the following functionality: +* [Basic operations on vectors](#vector). +* [Option types and operations on`Option` types](#option). +* [A common error encoding code interface for abort codes](#errors). +* [32-bit precision fixed-point numbers](#fixed_point32). + +Move标准库公开了实现以下功能的接口: +* [向量的基本操作](#向量). +* [Option类型与基本操作](#option). +* [终止码的常见错误编码接口](#errors). +* [32位精确定点数字](#fixed_point32). + +## 向量(vector) + + +The `vector` module defines a number of operations over the primitive +[`vector`](./vector.md) type. The module is published under the +named address `Std` and consists of a number of native functions, as +well as functions defined in Move. The API for this module is as follows. + +`向量`模块在原生类型[`向量`](./vector.md)上定义了许多操作。该模块以命名地址`Std`发布,并由许多原生函数以及在Move中定义的函数组成。此模块的API如下所示: + +### 函数(Functions) + +--------------------------------------------------------------------------- + +Create an empty [`vector`](./vector.md). +The `Element` type can be both a `resource` or `copyable` type. + +创建一个空的[`向量`](./vector.md)。 +`Element`类型可以是`资源`或`可复制`类型。 + +```move + native public fun empty(): vector; +``` + +--------------------------------------------------------------------------- + +Create a vector of length `1` containing the passed in `element`. + +创建一个长度为`1`的vector,并且包含传入的`element`。 + +```move + public fun singleton(e: Element): vector; +``` + +--------------------------------------------------------------------------- + +Destroy (deallocate) the vector `v`. Will abort if `v` is non-empty. +*Note*: The emptiness restriction is due to the fact that `Element` can be a +resource type, and destruction of a non-empty vector would violate +[resource conservation](./structs-and-resources.md). + +销毁(释放)向量`v`。如果`v`非空操作将终止。 +*注意*:空的限制是由于`Element`可以是资源类型,而销毁非空的向量会违反[资源保护机制](./structs-and-resources.md)。 + +```move + native public fun destroy_empty(v: vector); +``` + +--------------------------------------------------------------------------- + +Acquire an [immutable reference](./references.md) to the `i`th element of the vector `v`. Will abort if +the index `i` is out of bounds for the vector `v`. + +获取向量`v`的第`i`个元素的[不可变引用](./references.md)。如果索引`i`超出了向量`v`的范围,操作将会终止。 + +```move + native public fun borrow(v: &vector, i: u64): ∈ +``` + +--------------------------------------------------------------------------- + +Acquire a [mutable reference](./references.md) +to the `i`th element of the vector `v`. Will abort if +the index `i` is out of bounds for the vector `v`. + +获取向量`v`的第`i`个元素的[可变引用](./references.md)。如果索引`i`超出了向量`v`的范围,操作将会终止。 + +```move + native public fun borrow_mut(v: &mut vector, i: u64): &mut Element; +``` + +--------------------------------------------------------------------------- + +Empty and destroy the `other` vector, and push each of the elements in +the `other` vector onto the `lhs` vector in the same order as they occurred in `other`. + +清空并销毁`other`动态数组,并将`other`向量中的每个元素按顺序添加到`lhs`动态数组。 + +```move + public fun append(lhs: &mut vector, other: vector); +``` + +--------------------------------------------------------------------------- + +Push an element `e` of type `Element` onto the end of the vector `v`. May +trigger a resizing of the underlying vector's memory. + +将类型为`Element`的元素`e`添加到向量`v`的末尾。可能触发底层向量内存的大小调整。 + +```move + native public fun push_back(v: &mut vector, e: Element); +``` + +--------------------------------------------------------------------------- + +Pop an element from the end of the vector `v` in-place and return the owned +value. Will abort if `v` is empty. + +从向量`v`的末尾取出一个元素并返回。如果`v`为空将终止操作。 + +```move + native public fun pop_back(v: &mut vector): Element; +``` + +--------------------------------------------------------------------------- + +Remove the element at index `i` in the vector `v` and return the owned value +that was previously stored at `i` in `v`. All elements occurring at indices +greater than `i` will be shifted down by 1. Will abort if `i` is out of bounds +for `v`. + +移除向量`v`中索引`i`处的元素,并返回之前存储在`v`中的`i`处的值。所有下标大于`i`的元素将向前移动1个位置。如果`i`超出了`v`的范围,操作将会终止。 + +```move + public fun remove(v: &mut vector, i: u64): Element; +``` + +--------------------------------------------------------------------------- + +Swap the `i`th element of the vector `v` with the last element and then pop +this element off of the back of the vector and return the owned value that +was previously stored at index `i`. +This operation is O(1), but does not preserve ordering of elements in the vector. +Aborts if the index `i` is out of bounds for the vector `v`. + +将向量`v`的第`i`个元素与最后一个元素交换,然后将这个元素从向量的后面取出,并返回之前存储在索引`i`处的所有元素的值。 +这个操作时间复杂度是O(1),但是不保持向量容器中元素的顺序。 +如果索引`i`超出了向量`v`的边界,则操作终止。 + +```move + public fun swap_remove(v: &mut vector, i: u64): Element; +``` + +--------------------------------------------------------------------------- + +Swap the elements at the `i`'th and `j`'th indices in the vector `v`. Will +abort if either of `i` or `j` are out of bounds for `v`. + +交换向量`v`中下标为第`i`和第`j`的元素。如果`i`或`j`中的任何一个超出了`v`的范围,则操作将终止。 + +```move + native public fun swap(v: &mut vector, i: u64, j: u64); +``` + +--------------------------------------------------------------------------- + +Reverse the order of the elements in the vector `v` in-place. + +将向量v中的元素顺序颠倒。 + +```move + public fun reverse(v: &mut vector); +``` + +--------------------------------------------------------------------------- + +Return the index of the first occurrence of an element in `v` that is +equal to `e`. Returns `(true, index)` if such an element was found, and +`(false, 0)` otherwise. + +返回`v`中第一个与`e`相等的元素的索引。如果找到这样的元素,则返回`(true, index)`,否则返回`(false, 0)`。 + +```move + public fun index_of(v: &vector, e: &Element): (bool, u64); +``` + +--------------------------------------------------------------------------- +Return if an element equal to `e` exists in the vector `v`. + +如果向量`v`中存在等于`e`的元素,则返回true, 否则返回false。 + +```move + public fun contains(v: &vector, e: &Element): bool; +``` + +--------------------------------------------------------------------------- +Return the length of a `vector`. + +返回`向量`的长度。 + +```move + native public fun length(v: &vector): u64; +``` + +--------------------------------------------------------------------------- +Return whether the vector `v` is empty. + +如果向量`v`中没有元素,则返回true, 否则返回false。 + +```move + public fun is_empty(v: &vector): bool; +``` + +--------------------------------------------------------------------------- + +## 选项(option) + +The `option` module defines a generic option type `Option` that represents a +value of type `T` that may, or may not, be present. It is published under the named address `Std`. + +`option`模块定义了一个泛型option类型`Option`,它表示类型为`T`的值可能存在,也可能不存在。它发布在命名地址`Std`下。 + +The Move option type is internally represented as a singleton vector, and may +contain a value of `resource` or `copyable` kind. If you are familiar with option +types in other languages, the Move `Option` behaves similarly to those with a +couple notable exceptions since the option can contain a value of kind `resource`. +Particularly, certain operations such as `get_with_default` and +`destroy_with_default` require that the element type `T` be of `copyable` kind. + +Move option类型在内部表示为一个单例向量,可能包含`资源`或`可复制`类型的值。如果你熟悉其他语言中的option类型,Move `Option`的行为与那些类似,但有几个显著的例外,因为option可以包含一个类型为`资源`的值。 +特别地,某些操作如`get_with_default`和`destroy_with_default`要求元素类型`T`为`可复制`类型。 + +The API for the `option` module is as as follows + +`option`模块的API如下所示: + +### 类型(Types) + +Generic type abstraction of a value that may, or may not, be present. Can contain +a value of either `resource` or `copyable` kind. + +一个值的泛型类型的抽象,可能存在,也可能不存在。它可以包含`资源`或`可复制`类型的值。 + +```move + struct Option; +``` + +### 函数(Functions) + +Create an empty `Option` of that can contain a value of `Element` type. + +创建一个可以包含`Element`类型值的空`Option`。 + +```move + public fun none(): Option; +``` + +--------------------------------------------------------------------------- + +Create a non-empty `Option` type containing a value `e` of type `Element`. + +创建一个非空的`Option`类型,包含类型为`Element`的值`e`。 + +```move + public fun some(e: T): Option; +``` + +--------------------------------------------------------------------------- + +Return an immutable reference to the value inside the option `opt_elem` +Will abort if `opt_elem` does not contain a value. + +返回`opt_elem`内部值的不可变引用,如果`opt_elem`不包含值,则将终止操作。 + +```move + public fun borrow(opt_elem: &Option): ∈ +``` + +--------------------------------------------------------------------------- + +Return a reference to the value inside `opt_elem` if it contains one. If +`opt_elem` does not contain a value the passed in `default_ref` reference will be returned. +Does not abort. + +如果`opt_elem`中包含值,则返回该值的引用。如果`opt_elem`不包含值,将返回传入的`default_ref`引用。不会终止操作。 + +```move + public fun borrow_with_default(opt_elem: &Option, default_ref: &Element): ∈ +``` + +--------------------------------------------------------------------------- + +Return a mutable reference to the value inside `opt_elem`. Will abort if +`opt_elem` does not contain a value. + +返回`opt_elem`内部值的可变引用。如果`opt_elem`不包含值,则操作将终止。 + +```move + public fun borrow_mut(opt_elem: &mut Option): &mut Element; +``` + +--------------------------------------------------------------------------- + +Convert an option value that contains a value to one that is empty in-place by +removing and returning the value stored inside `opt_elem`. +Will abort if `opt_elem` does not contain a value. + +通过删除并返回存储在`opt_elem`中的值,将包含值的`opt_elem`转换为空option类型。 +如果`opt_elem`不包含值,则将终止。 + +```move + public fun extract(opt_elem: &mut Option): Element; +``` + +--------------------------------------------------------------------------- + +Return the value contained inside the option `opt_elem` if it contains one. +Will return the passed in `default` value if `opt_elem` does not contain a +value. The `Element` type that the `Option` type is instantiated with must be +of `copyable` kind in order for this function to be callable. + +如果`opt_elem`中包含值,则返回该值。 +如果`opt_elem`不包含值,将返回传入的`default`值。`default`类型必须是`可复制`类型,这样该函数才能被调用。 + +```move + public fun get_with_default(opt_elem: &Option, default: Element): Element; +``` + +--------------------------------------------------------------------------- + +Convert an empty option `opt_elem` to an option value that contains the value `e`. +Will abort if `opt_elem` already contains a value. + +将空option类型`opt_elem`转换为包含值`e`的option类。 +如果`opt_elem`已经包含值,则操作将终止。 + +```move + public fun fill(opt_elem: &mut Option, e: Element); +``` + +--------------------------------------------------------------------------- + +Swap the value currently contained in `opt_elem` with `new_elem` and return the +previously contained value. Will abort if `opt_elem` does not contain a value. + +将`opt_elem`当前包含的值与`new_elem`交换,并返回先前包含的值。如果`opt_elem`不包含值,则操作将终止。 + +```move + public fun swap(opt_elem: &mut Option, e: Element): Element; +``` + +--------------------------------------------------------------------------- + +Return true if `opt_elem` contains a value equal to the value of `e_ref`. +Otherwise, `false` will be returned. + +如果`opt_elem`包含一个等于`e_ref`的值,则返回`true`。否则,将返回`false`。 + +```move + public fun contains(opt_elem: &Option, e_ref: &Element): bool; +``` + +--------------------------------------------------------------------------- + +Return `true` if `opt_elem` does not contain a value. + +如果`opt_elem`不包含值,则返回`true`。 + +```move + public fun is_none(opt_elem: &Option): bool; +``` + +--------------------------------------------------------------------------- + +Return `true` if `opt_elem` contains a value. + +如果`opt_elem`包含值,则返回`true`。 + +```move + public fun is_some(opt_elem: &Option): bool; +``` + +--------------------------------------------------------------------------- + +Unpack `opt_elem` and return the value that it contained. +Will abort if `opt_elem` does not contain a value. + +解包`opt_elem`并返回它所包含的值。 +如果`opt_elem`不包含值,则操作将终止。 + +```move + public fun destroy_some(opt_elem: Option): Element; +``` + +--------------------------------------------------------------------------- + +Destroys the `opt_elem` value passed in. If `opt_elem` contained a value it +will be returned otherwise, the passed in `default` value will be returned. + +销毁传入的`opt_elem`。如果`opt_elem`包含值,它将被返回,否则将返回传入的`default`值。 + +```move + public fun destroy_with_default(opt_elem: Option, default: Element): Element; +``` + +--------------------------------------------------------------------------- + +Destroys the `opt_elem` value passed in, `opt_elem` must be empty and not +contain a value. Will abort if `opt_elem` contains a value. + +销毁传入的`opt_elem`,`opt_elem`必须为空且不包含值。如果`opt_elem`包含一个值,则会终止操作。 + +```move + public fun destroy_none(opt_elem: Option); +``` + +## 错误(errors) + +Recall that each abort code in Move is represented as an unsigned 64-bit integer. The `errors` module defines a common interface that can be used to "tag" each of these abort codes so that they can represent both the error **category** along with an error **reason**. + +回想一下,Move中的每个终止代码都表示为无符号64位整数。`errors`模块定义了一个通用接口,可用于"标记"每个终止代码,以便它们既可以表示错误**类别**,也可以表示错误**原因**。 + +Error categories are declared as constants in the `errors` module and are globally unique with respect to this module. Error reasons on the other hand are module-specific error codes, and can provide greater detail (perhaps, even a particular _reason_) about the specific error condition. This representation of a category and reason for each error code is done by dividing the abort code into two sections. + +错误类别在`errors`模块中声明为常量,并且对该模块来说是全局唯一的。另一方面,错误原因是特定于模块的错误代码,可以提供关于特定错误条件的更详细的信息(甚至可能是一个特定的_reason_)。每个错误代码的类别和原因的这种表示是通过将终止代码分成两部分来完成的。 + +The lower 8 bits of the abort code hold the *error category*. The remaining 56 bits of the abort code hold the *error reason*. +The reason should be a unique number relative to the module which raised the error and can be used to obtain more information about the error at hand. It should mostly be used for diagnostic purposes as error reasons may change over time if the module is updated. + +| Category | Reason | +|----------|--------| +| 8 bits | 56 bits| + +Since error categories are globally stable, these present the most stable API and should in general be what is used by clients to determine the messages they may present to users (whereas the reason is useful for diagnostic purposes). There are public functions in the `errors` module for creating an abort code of each error category with a specific `reason` number (represented as a `u64`). + +终止代码的较低8位保存*错误类别*。终止代码的其余56位包含*错误原因*。 +原因应该是相对于引发错误的模块的唯一数字,并且可以用来获取关于当前错误的更多信息。它应该主要用于诊断目的,因为如果模块更新,错误原因可能会随着时间的推移而变化。 + +| 类型 | 原因 | +|----------|--------| +| 8 bits | 56 bits| + +由于错误类别是全局稳定的,所以它们提供了稳定的API,通常应该由客户端用来确定它们可能向用户提供的消息(而原因则用于诊断目的)。在`errors`模块中有一些公共函数,用于创建每个错误类别的带有特定`原因`号的终止代码(表示为`u64`)。 + +### 常量(Constants) + +The system is in a state where the performed operation is not allowed. + +系统处于不允许操作的状态。 + +```move + const INVALID_STATE: u8 = 1; +``` + +--------------------------------------------------------------------------- +A specific account address was required to perform an operation, but a different address from what was expected was encounterd. + +执行操作需要一个特定的帐户地址,但遇到的地址与预期的不同。 + +```move + const REQUIRES_ADDRESS: u8 = 2; +``` + +--------------------------------------------------------------------------- +An account did not have the expected role for this operation. Useful for Role Based Access Control (RBAC) error conditions. + +帐户没有此操作的预期角色。用于基于角色访问控制(RBAC)错误。 + +```move + const REQUIRES_ROLE: u8 = 3; +``` + +--------------------------------------------------------------------------- +An account did not not have a required capability. Useful for RBAC error conditions. + +帐户没有所需的能力。用于RBAC错误。 + +```move + const REQUIRES_CAPABILITY: u8 = 4; +``` + +--------------------------------------------------------------------------- +A resource was expected, but did not exist under an address. + +地址下不存在期望的资源。 + +```move + const NOT_PUBLISHED: u8 = 5; +``` + +--------------------------------------------------------------------------- +Attempted to publish a resource under an address where one was already published. + +试图在已发布资源的地址发布资源。 + +```move + const ALREADY_PUBLISHED: u8 = 6; +``` + +--------------------------------------------------------------------------- +An argument provided for an operation was invalid. + +为操作提供的参数无效。 + +```move + const INVALID_ARGUMENT: u8 = 7; +``` + +--------------------------------------------------------------------------- +A limit on a value was exceeded. + +超过了一个值的限制。 + +```move + const LIMIT_EXCEEDED: u8 = 8; +``` + +--------------------------------------------------------------------------- +An internal error (bug) has occurred. + +发生了内部错误(bug)。 + +```move + const INTERNAL: u8 = 10; +``` + +--------------------------------------------------------------------------- +A custom error category for extension points. + +扩展自定义错误类别。 + +```move + const CUSTOM: u8 = 255; +``` + +--------------------------------------------------------------------------- + +### 函数(Functions) + + Should be used in the case where invalid (global) state is encountered. Constructs an abort code with specified `reason` and category `INVALID_STATE`. Will abort if `reason` does not fit in 56 bits. + +在遇到无效(全局)状态的情况下应使用。构造一个具有指定的`reason`和类别`INVALID_STATE`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun invalid_state(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an account's address does not match a specific address. Constructs an abort code with specified `reason` and category `REQUIRES_ADDRESS`. Will abort if `reason` does not fit in 56 bits. + +当账户地址与特定地址不匹配时应使用。构造一个具有指定的`reason`和类别`REQUIRES_ADDRESS`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun requires_address(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a role did not match a required role when using RBAC. Constructs an abort code with specified `reason` and category `REQUIRES_ROLE`. Will abort if `reason` does not fit in 56 bits. + +在使用RBAC时,角色与所需角色不匹配时应使用。构造一个具有指定的`reason`和类别`REQUIRES_ROLE`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun requires_role(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an account did not have a required capability when using RBAC. Constructs an abort code with specified `reason` and category `REQUIRES_CAPABILITY`. Should be Will abort if `reason` does not fit in 56 bits. + +在使用RBAC时,帐户没有必要的能力时应使用。构造一个具有指定的`reason`和类别`REQUIRES_CAPABILITY`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun requires_capability(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a resource did not exist where one was expected. Constructs an abort code with specified `reason` and category `NOT_PUBLISHED`. Will abort if `reason` does not fit in 56 bits. + +在需要资源的地方不存在资源时应使用。构造一个具有指定的`reason`和类别`NOT_PUBLISHED`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun not_published(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a resource already existed where one was about to be published. Constructs an abort code with specified `reason` and category `ALREADY_PUBLISHED`. Will abort if `reason` does not fit in 56 bits. + +要发布资源的地方已经存在资源时使用。构造一个具有指定的`reason`和类别`ALREADY_PUBLISHED`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun already_published(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an invalid argument was passed to a function/operation. Constructs an abort code with specified `reason` and category `INVALID_ARGUMENT`. Will abort if `reason` does not fit in 56 bits. + +当向函数/操作传递无效参数时使用。构造一个具有指定的`reason`和类别`INVALID_ARGUMENT`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun invalid_argument(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if a limit on a specific value is reached, e.g., subtracting 1 from a value of 0. Constructs an abort code with specified `reason` and category `LIMIT_EXCEEDED`. Will abort if `reason` does not fit in 56 bits. + +当达到特定值的限制时应使用,例如,0减去1。构造一个具有指定的`reason`和类别`LIMIT_EXCEEDED`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun limit_exceeded(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Should be used if an internal error or bug was encountered. Constructs an abort code with specified `reason` and category `INTERNAL`. Will abort if `reason` does not fit in 56 bits. + +在遇到内部错误或错误时使用。构造一个具有指定的`reason`和类别`INTERNAL`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun internal(reason: u64): u64; +``` + +--------------------------------------------------------------------------- +Used for extension points, should be not used under most circumstances. Constructs an abort code with specified `reason` and category `CUSTOM`. Will abort if `reason` does not fit in 56 bits. + +用于扩展,大多数情况下不应使用。构造一个具有指定的`reason`和类别`CUSTOM`的终止代码。如果`reason`不适合56位,将会终止操作。 + +```move + public fun custom(reason: u64): u64; +``` + +--------------------------------------------------------------------------- + +## 32位精确定点数字(fixed_point32) + +The `fixed_point32` module defines a fixed-point numeric type with 32 integer bits and 32 fractional bits. Internally, this is represented as a `u64` integer wrapped in a struct to make a unique `fixed_point32` type. Since the numeric representation is a binary one, some decimal values may not be exactly representable, but it provides more than 9 decimal digits of precision both before and after the decimal point (18 digits total). For comparison, double precision floating-point has less than 16 decimal digits of precision, so you should be careful about using floating-point to convert these values to decimal. + +`fixed_point32`模块定义了一个具有32个整数位和32个小数位的定点数值类型。在内部,它被表示为一个`u64`整数,包装在一个结构中,形成一个唯一的`fixed_point32`类型。由于数字表示是二进制的,一些十进制值可能不能完全表示,但它在小数点之前和之后都提供了9位以上的十进制精度(总共18位)。为了进行比较,双精度浮点数的精度小于16位十进制数字,因此在使用浮点数将这些值转换为十进制时应该小心。 + +### 类型(Types) +Represents a fixed-point numeric number with 32 fractional bits. + +表示具有32个小数位的定点数字。 + +```move + struct FixedPoint32; +``` + +### 函数(Functions) + +Multiply a u64 integer by a fixed-point number, truncating any fractional part of the product. This will abort if the product overflows. + +当u64整数乘以定点数,截断乘积的任何小数部分。如果乘积溢出,该操作将终止。 + +```move + public fun multiply_u64(val: u64, multiplier: FixedPoint32): u64; +``` + +--------------------------------------------------------------------------- +Divide a u64 integer by a fixed-point number, truncating any fractional part of the quotient. This will abort if the divisor is zero or if the quotient overflows. + +当u64整数除以定点数,截断商的任何小数部分。如果除数为零或商溢出,该操作将终止。 + +```move + public fun divide_u64(val: u64, divisor: FixedPoint32): u64; +``` + +--------------------------------------------------------------------------- +Create a fixed-point value from a rational number specified by its numerator and denominator. Calling this function should be preferred for using `fixed_point32::create_from_raw_value` which is also available. This will abort if the denominator is zero. It will also abort if the numerator is nonzero and the ratio is not in the range $2^{-32}\ldots2^{32}-1$. When specifying decimal fractions, be careful about rounding errors: if you round to display $N$ digits after the decimal point, you can use a denominator of $10^N$ to avoid numbers where the very small imprecision in the binary representation could change the rounding, e.g., 0.0125 will round down to 0.012 instead of up to 0.013. + +根据分子和分母指定的有理数创建定点值。如果`fixed_point32::create_from_raw_value`函数可用,应优先使用。如果分母为零,该操作将终止。如果分子非零且比值不在$2^{-32}\ldots2^{32}-1$范围内,该操作将终止。指定小数时,请注意四舍五入错误:如果要对小数点后$N$位进行四舍五入,则可以用$10^N$做分母,这样就能避免精确度丢失问题,例如,0.0125将四舍五入到0.012而不是0.013。 + +```move + public fun create_from_rational(numerator: u64, denominator: u64): FixedPoint32; +``` + +--------------------------------------------------------------------------- +Create a fixedpoint value from a raw `u64` value. + +通过`u64`原始值创建一个定点值。 + +```move + public fun create_from_raw_value(value: u64): FixedPoint32; +``` + +--------------------------------------------------------------------------- +Returns `true` if the decimal value of `num` is equal to zero. + +如果`num`的十进制值等于0,则返回`true`。 + +```move + public fun is_zero(num: FixedPoint32): bool; +``` + +--------------------------------------------------------------------------- +Accessor for the raw `u64` value. Other less common operations, such as adding or subtracting `FixedPoint32` values, can be done using the raw values directly. + +获取`u64`原始值的方法。其他不太常见的操作,例如添加或减去`FixedPoint32`值,可以直接使用原始值来完成。 + +```move + public fun get_raw_value(num: FixedPoint32): u64; +``` + +--------------------------------------------------------------------------- diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/structs-and-resources.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/structs-and-resources.md new file mode 100644 index 000000000..9dcf97c95 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/structs-and-resources.md @@ -0,0 +1,591 @@ +# 结构体和资源 + +A _struct_ is a user-defined data structure containing typed fields. Structs can store any +non-reference type, including other structs. + +***结构体***(struct)是包含类型字段的自定义数据结构。结构体可以存储任何非引用类型,包括其他结构。 + +We often refer to struct values as _resources_ if they cannot be copied and cannot be dropped. In +this case, resource values must have ownership transferred by the end of the function. This property +makes resources particularly well served for defining global storage schemas or for representing +important values (such as a token). + +如果结构值无法复制且无法删除,我们通常将其称为***资源***(resource)。在这种情况下,资源值必须在函数结束时转移所有权。这个属性使资源特别适合定义全局存储模式或表示重要的值(如 token)。 + +By default, structs are linear and ephemeral. By this we mean that they: cannot be copied, cannot be +dropped, and cannot be stored in global storage. This means that all values have to have ownership +transferred (linear) and the values must be dealt with by the end of the program's execution +(ephemeral). We can relax this behavior by giving the struct [abilities](./abilities.md) which allow +values to be copied or dropped and also to be stored in global storage or to define global storage +schemas. + +默认情况下,结构体是线性的和临时的。我们的意思是它们:不能被复制,不能被删除,不能被存储在全局存储中。这意味着所有值都必须转移所有权(线性),并且必须在程序执行结束时处理这些值(临时)。我们可以通过赋予结构体允许复制或删除值以及将值存储在全局存储中或定义全局存储模式的[能力](./abilities.md)来放松这种行为(减轻限制)。 + +## 定义结构体 + +Structs must be defined inside a module: + +结构体必须在模块内定义: + +```move +address 0x2 { +module m { + struct Foo { x: u64, y: bool } + struct Bar {} + struct Baz { foo: Foo, } + // ^ 注意:尾随逗号是可以的 +} +} +``` + +Structs cannot be recursive, so the following definition is invalid: + +结构体不能递归(定义),所以下面的定义是无效的: + +```move +struct Foo { x: Foo } +// ^ 错误! Foo 不能包含 Foo +``` + +As mentioned above: by default, a struct declaration is linear and ephemeral. So to allow the value +to be used with certain operations (that copy it, drop it, store it in global storage, or use it as +a storage schema), structs can be granted [abilities](./abilities.md) by annotating them with +`has `: + +如上所述:默认情况下,结构体声明是线性且临时的。因此,为了允许将值用于某些操作(复制、删除、将其存储在全局存储中或将其用作存储模式),可以通过使用 `has ` 标注它们来授予结构体[能力](./abilities.md): + +```move +address 0x2 { +module m { + struct Foo has copy, drop { x: u64, y: bool } +} +} +``` + +For more details, see the [annotating structs](./abilities.md#annotating-structs) section. + +有关更多详细信息,请参阅[标注结构体](./abilities.md#标注结构体)部分。 + +### 命名 + +Structs must start with a capital letter `A` to `Z`. After the first letter, constant names can +contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, or digits `0` to `9`. + +结构体必须以大写字母 `A` 到 `Z` 开头。在第一个字母之后,结构体名称可以包含下划线 `_`、字母 `a` 到 `z`、字母 `A` 到 `Z` 或数字 `0` 到 `9`。 + +```move +struct Foo {} +struct BAR {} +struct B_a_z_4_2 {} +``` + +This naming restriction of starting with `A` to `Z` is in place to give room for future language +features. It may or may not be removed later. + +这种以 `A` 到 `Z` 开头的命名限制是为了给未来的语言特性留出空间。以后可能会也可能不会删除这个限制。 + +## 使用结构体 + +### 创建结构体 + +Values of a struct type can be created (or "packed") by indicating the struct name, followed by +value for each field: + +可以通过写明结构体名称来创建(或“打包”)结构体类型的值,然后是每个字段的值: + +```move +address 0x2 { +module m { + struct Foo has drop { x: u64, y: bool } + struct Baz has drop { foo: Foo } + + fun example() { + let foo = Foo { x: 0, y: false }; + let baz = Baz { foo: foo }; + } +} +} +``` + +If you initialize a struct field with a local variable whose name is the same as the field, you can +use the following shorthand: + +如果使用与字段名相同的局部变量初始化结构体字段,则可以使用以下简写: + +```move +let baz = Baz { foo: foo }; +// 相当于 +let baz = Baz { foo }; +``` + +This is called sometimes called "field name punning". + +这有时称为“字段名双关语”。 + +### 通过模式匹配销毁结构体 + +Struct values can be destroyed by binding or assigning them patterns. + +结构值可以通过绑定或赋值模式来销毁。 + +```move +address 0x2 { +module m { + struct Foo { x: u64, y: bool } + struct Bar { foo: Foo } + struct Baz {} + + fun example_destroy_foo() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y: foo_y } = foo; + // ^ `x: x` 的简写 + + // 两个新绑定 + // x: u64 = 3 + // foo_y: bool = false + } + + fun example_destroy_foo_wildcard() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y: _ } = foo; + + // 由于 y 绑定到通配符,因此只有一个新绑定 + // x: u64 = 3 + } + + fun example_destroy_foo_assignment() { + let x: u64; + let y: bool; + Foo { x, y } = Foo { x: 3, y: false }; + + // 改变现有变量 x 和 y + // x = 3, y = false + } + + fun example_foo_ref() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y } = &foo; + + // 两个新绑定 + // x: &u64 + // y: &bool + } + + fun example_foo_ref_mut() { + let foo = Foo { x: 3, y: false }; + let Foo { x, y } = &mut foo; + + // 两个新绑定 + // x: &mut u64 + // y: &mut bool + } + + fun example_destroy_bar() { + let bar = Bar { foo: Foo { x: 3, y: false } }; + let Bar { foo: Foo { x, y } } = bar; + // ^ 嵌套模式 + + // 两个新绑定 + // x: u64 = 3 + // y: bool = false + } + + fun example_destroy_baz() { + let baz = Baz {}; + let Baz {} = baz; + } +} +} +``` + +### 借用结构体和字段 + +The `&` and `&mut` operator can be used to create references to structs or fields. These examples +include some optional type annotations (e.g., `: &Foo`) to demonstrate the type of operations. + +`&` 和 `&mut` 运算符可用于创建对结构体或字段的引用。这些例子包括一些可选的类型标注(例如,`: &Foo`)来演示操作的类型。 + +```move +let foo = Foo { x: 3, y: true }; +let foo_ref: &Foo = &foo; +let y: bool = foo_ref.y; // 通过对结构体的引用读取字段 +let x_ref: &u64 = &foo.x; + +let x_ref_mut: &mut u64 = &mut foo.x; +*x_ref_mut = 42; // 通过可变引用修改字段 +``` + +It is possible to borrow inner fields of nested structs. + +可以借用嵌套结构体的内部字段: + +```move +let foo = Foo { x: 3, y: true }; +let bar = Bar { foo }; + +let x_ref = &bar.foo.x; +``` + +You can also borrow a field via a reference to a struct. + +你还可以通过对结构体的引用来借用字段: + +```move +let foo = Foo { x: 3, y: true }; +let foo_ref = &foo; +let x_ref = &foo_ref.x; +// 这与 let x_ref = &foo.x 的效果相同 +``` + +### 读写字段 + +If you need to read and copy a field's value, you can then dereference the borrowed field + +如果你需要读取和复制字段的值,则可以解引用借用的字段: + +```move +let foo = Foo { x: 3, y: true }; +let bar = Bar { foo: copy foo }; +let x: u64 = *&foo.x; +let y: bool = *&foo.y; +let foo2: Foo = *&bar.foo; +``` + +If the field is implicitly copyable, the dot operator can be used to read fields of a struct without +any borrowing. (Only scalar values with the `copy` ability are implicitly copyable.) + +如果该字段是隐式可复制的,则点运算符可用于读取结构体的字段而无需任何借用。(只有具有 `copy` 能力的标量值是隐式可复制的。) + +```move +let foo = Foo { x: 3, y: true }; +let x = foo.x; // x == 3 +let y = foo.y; // y == true +``` + +Dot operators can be chained to access nested fields. + +点运算符可以链式访问嵌套字段: + +```move +let baz = Baz { foo: Foo { x: 3, y: true } }; +let x = baz.foo.x; // x = 3; +``` + +However, this is not permitted for fields that contain non-primitive types, such a vector or another +struct + +但是,对于包含非原始类型(例如向量或其他结构体)的字段,这是不允许的: + +```move +let foo = Foo { x: 3, y: true }; +let bar = Bar { foo }; +let foo2: Foo = *&bar.foo; +let foo3: Foo = bar.foo; // 错误!必须使用 *& 添加显式复制 +``` + +The reason behind this design decision is that copying a vector or another struct might be an +expensive operation. It is important for a programmer to be aware of this copy and make others aware +with the explicit syntax `*&` + +In addition reading from fields, the dot syntax can be used to modify fields, regardless of the +field being a primitive type or some other struct + +这个设计决策背后的原因是复制一个向量或另一个结构体可能是一项昂贵的操作。对于程序员来说,了解这个复制(操作)并使用显式语法 `*&` 让其他人意识到是很重要的。 + +除了从字段中读取之外,点语法还可用于修改字段,无论该字段是原始类型还是其他结构体。 + +```move +let foo = Foo { x: 3, y: true }; +foo.x = 42; // foo = Foo { x: 42, y: true } +foo.y = !foo.y; // foo = Foo { x: 42, y: false } +let bar = Bar { foo }; // bar = Bar { foo: Foo { x: 42, y: false } } +bar.foo.x = 52; // bar = Bar { foo: Foo { x: 52, y: false } } +bar.foo = Foo { x: 62, y: true }; // bar = Bar { foo: Foo { x: 62, y: true } } +``` + +The dot syntax also works via a reference to a struct + +点语法也适用于对结构体的引用: + +```move +let foo = Foo { x: 3, y: true }; +let foo_ref = &mut foo; +foo_ref.x = foo_ref.x + 1; +``` + +## 私有结构体操作 + +Most struct operations on a struct type `T` can only be performed inside the module that declares +`T`: + +- Struct types can only be created ("packed"), destroyed ("unpacked") inside the module that defines + the struct. +- The fields of a struct are only accessible inside the module that defines the struct. + +Following these rules, if you want to modify your struct outside the module, you will need to +provide public APIs for them. The end of the chapter contains some examples of this. + +However, struct _types_ are always visible to another module or script: + +大多数对结构体类型 `T` 的结构体操作只能在声明 `T` 的模块内执行: + +- 结构体类型只能在定义结构体的模块内创建(“打包”)、销毁(“解包”)。 +- 结构体的字段只能在定义结构体的模块内部访问。 + +按照这些规则,如果你想在模块之外修改你的结构体,你需要为他们提供公共 API。本章的最后包含了这方面的一些例子。 + +但是,结构体类型始终对其他模块或脚本可见: + +```move +// m.move +address 0x2 { +module m { + struct Foo has drop { x: u64 } + + public fun new_foo(): Foo { + Foo { x: 42 } + } +} +} +``` + +```move +// n.move +address 0x2 { +module n { + use 0x2::m; + + struct Wrapper has drop { + foo: m::Foo + } + + fun f1(foo: m::Foo) { + let x = foo.x; + // ^ 错误!此处无法访问 `foo` 的字段 + } + + fun f2() { + let foo_wrapper = Wrapper { foo: m::new_foo() }; + } +} +} +``` + +Note that structs do not have visibility modifiers (e.g., `public` or `private`). + +请注意,结构体没有可见性修饰符(例如,`public` 或 `private`)。 + +## 所有权 + +As mentioned above in [Defining Structs](#defining-structs), structs are by default linear and +ephemeral. This means they cannot be copied or dropped. This property can be very useful when +modeling real world resources like money, as you do not want money to be duplicated or get lost in +circulation. +正如上面[定义结构体](#定义结构体)中提到的,结构体默认是线性的和临时的。这意味着它们不能被复制或删除。在模拟货币等现实世界资源时,此属性非常有用,因为你不希望货币被复制或在流通中丢失。 + +```move +address 0x2 { +module m { + struct Foo { x: u64 } + + public fun copying_resource() { + let foo = Foo { x: 100 }; + let foo_copy = copy foo; // 错误!“复制”需要“复制”能力 + let foo_ref = &foo; + let another_copy = *foo_ref // 错误!解引用需要“复制”能力 + } + + public fun destroying_resource1() { + let foo = Foo { x: 100 }; + + // 错误!当函数返回时,foo 仍然包含一个值。 + // 这种销毁需要“drop”能力 + } + + public fun destroying_resource2(f: &mut Foo) { + *f = Foo { x: 100 } // 错误!通过写入销毁旧值需要“drop”能力 + } +} +} +``` + +To fix the second example (`fun dropping_resource`), you would need to manually "unpack" the resource: + +要修复第二个示例(`fun destroying_resource1`),你需要手动“解包”资源: + +```move +address 0x2 { +module m { + struct Foo { x: u64 } + + public fun destroying_resource1_fixed() { + let foo = Foo { x: 100 }; + let Foo { x: _ } = foo; + } +} +} +``` + +Recall that you are only able to deconstruct a resource within the module in which it is defined. +This can be leveraged to enforce certain invariants in a system, for example, conservation of money. + +If on the other hand, your struct does not represent something valuable, you can add the abilities +`copy` and `drop` to get a struct value that might feel more familiar from other programming +languages: + +回想一下,你只能在定义资源的模块中解构资源。这可以用来在系统中强制执行某些不变量,例如货币守恒。 + +另一方面,如果你的结构体不代表有价值的东西,你可以添加 `copy` 和 `drop` 能力来获取一个结构值,这感觉可能会与其他编程语言更相似。 + +```move +address 0x2 { +module m { + struct Foo has copy, drop { x: u64 } + + public fun run() { + let foo = Foo { x: 100 }; + let foo_copy = copy foo; + // ^ 此代码复制 foo,而 `let x = foo` 或 + // `let x = move foo` 都移动 foo + + let x = foo.x; // x = 100 + let x_copy = foo_copy.x; // x = 100 + + // 函数返回时 foo 和 foo_copy 都被隐式丢弃 + } +} +} +``` + +## 在全局存储中存储资源 + +Only structs with the `key` ability can be saved directly in +[persistent global storage](./global-storage-operators.md). All values stored within those `key` +structs must have the `store` abilities. See the [ability](./abilities] and +[global storage](./global-storage-operators.md) chapters for more detail. + +只有具有 `key` 能力的结构体才能直接保存在[持久性全局存储](./global-storage-operators.md)中。存储在这些 `key` 结构体中的所有值都必须具有 `store` 能力。有关更多详细信息,请参阅[能力](./abilities.md)和[全局存储](./global-storage-operators.md)章节。 + +## 示例 + +Here are two short examples of how you might use structs to represent valuable data (in the case of +`Coin`) or more classical data (in the case of `Point` and `Circle`) + +这里有两个简短的示例,说明如何使用结构体来表示有价值的数据(在 `Coin` 的情况下)或更经典的数据(在 `Point` 和 `Circle` 的情况下)。 + +### 示例 1:Coin + + + +```move +address 0x2 { +module m { + // 我们不希望钱币(Coin)被复制,因为那会复制这个“钱”, + // 所以我们不会给结构体“copy”能力。 + // 同样,我们不希望程序员销毁钱币,所以我们不会给结构体“drop”能力。 + // 但是,我们*希望*模块的用户能够将这个钱币存储在持久的全局存储中, + // 所以我们授予结构体“store”能力。 + // 这个结构体只会在全局存储内的其他资源中,因此我们不会赋予该结构体“key”能力。 + struct Coin has store { + value: u64, + } + + public fun mint(value: u64): Coin { + // 你可能希望通过某种形式的访问控制来关闭此(铸币)功能,以防止使用此模块的任何人铸造无限数量的钱币。 + Coin { value } + } + + public fun withdraw(coin: &mut Coin, amount: u64): Coin { + assert!(coin.balance >= amount, 1000); + coin.value = coin.value - amount; + Coin { value: amount } + } + + public fun deposit(coin: &mut Coin, other: Coin) { + let Coin { value } = other; + coin.value = coin.value + value; + } + + public fun split(coin: Coin, amount: u64): (Coin, Coin) { + let other = withdraw(&mut coin, amount); + (coin, other) + } + + public fun merge(coin1: Coin, coin2: Coin): Coin { + deposit(&mut coin1, coin2); + coin1 + } + + public fun destroy_zero(coin: Coin) { + let Coin { value } = coin; + assert!(value == 0, 1001); + } +} +} +``` + +### 示例 2:Geometry + +```move +address 0x2 { +module point { + struct Point has copy, drop, store { + x: u64, + y: u64, + } + + public fun new(x: u64, y: u64): Point { + Point { + x, y + } + } + + public fun x(p: &Point): u64 { + p.x + } + + public fun y(p: &Point): u64 { + p.y + } + + fun abs_sub(a: u64, b: u64): u64 { + if (a < b) { + b - a + } + else { + a - b + } + } + + public fun dist_squared(p1: &Point, p2: &Point): u64 { + let dx = abs_sub(p1.x, p2.x); + let dy = abs_sub(p1.y, p2.y); + dx*dx + dy*dy + } +} +} +``` + +```move +address 0x2 { +module circle { + use 0x2::point::{Self, Point}; + + struct Circle has copy, drop, store { + center: Point, + radius: u64, + } + + public fun new(center: Point, radius: u64): Circle { + Circle { center, radius } + } + + public fun overlaps(c1: &Circle, c2: &Circle): bool { + let d = point::dist_squared(&c1.center, &c2.center); + let r1 = c1.radius; + let r2 = c2.radius; + d*d <= r1*r1 + 2*r1*r2 + r2*r2 + } +} +} +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/tuples.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/tuples.md new file mode 100644 index 000000000..b3182e8c2 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/tuples.md @@ -0,0 +1,117 @@ +# 元组和单值 + +Move 不完全支持元组,因为人们可能期望像来自另一种语言的元组一样将它们作为[头等值(即头等公民)](https://zh.wikipedia.org/wiki/%E9%A0%AD%E7%AD%89%E7%89%A9%E4%BB%B6)。但是,为了支持多个返回值,Move 具有类似元组的表达式。这些表达式在运行时不会产生具体的值(字节码中没有元组),因此它们非常有限:它们只能出现在表达式中(通常在函数的返回位置);它们不能绑定到局部变量;它们不能存储在结构中;元组类型不能用于实例化泛型。 + +类似地,[单值(unit)`()`](https://zh.wikipedia.org/wiki/%E5%8D%95%E5%80%BC%E7%B1%BB%E5%9E%8B) 是 Move 源语言创建的一种以表达式为基础的类型。单值 `()` 不会产生任何运行时值。我们可以认为单值 `()` 是一个空元组,适用于元组的任何限制也适用于单值。 + +考虑到这些限制,在语言中使用元组可能会感觉很奇怪。但其他语言中,元组最常见的用例之一是函数 —— 允许函数返回多个值。一些语言通过强制用户编写包含多个返回值的结构来解决这个问题。但是在 Move 中,您不能将引用放在[结构体](./structs-and-resources.md)中。这需要 Move 支持多个返回值。这些多个返回值都在字节码级别被压入到堆栈中。在源码级别,这些多个返回值使用元组表示。 + +## 字面量 + +元组(tuple)是由括号内以逗号分隔的表达式列表创建的。 + +| 语法 | 类型 | 描述 | +|-----------------|-----------------------------------------------------------------------------|-----------------------------------------| +| `()` | `(): ()` | 单值、空元组或 0 元素元组 | +| `(e1, ..., en)` | `(e1, ..., en): (T1, ..., Tn)` 其中 `e_i: Ti` 满足 `0 < i <= n` and `n > 0` | n 元组、n 元素元组、带有 n 个元素的元组 | + +注意 `(e)` 没有类型 `(e): (t)`,换句话说,没有一个元素的元组。如果括号内只有一个元素,则括号仅用于消除歧义,不带有任何其他特殊含义。 + +有时,具有两个元素的元组称为“二元组(pairs)”,而具有三个元素的元组称为“三元组(triples)”。 + +### 例子 + +```move +address 0x42 { +module example { + // 这三个函数都是等价的 + + // 当没有提供返回类型时,假定为 `()` + fun returns_unit_1() { } + + // 空表达式块中存在隐式 () 值 + fun returns_unit_2(): () { } + + // `returns_unit_1` 和 `returns_unit_2` 的显式版本 + fun returns_unit_3(): () { () } + + + fun returns_3_values(): (u64, bool, address) { + (0, false, @0x42) + } + fun returns_4_values(x: &u64): (&u64, u8, u128, vector) { + (x, 0, 1, b"foobar") + } +} +} +``` + +## 操作 + +目前唯一可以对元组执行的操作是解构(destructuring)。 + +### 解构 + +对于任何大小的元组,它们可以在 `let` 绑定或赋值中被解构。 + +例如: + +```move +address 0x42 { +module example { + // 这三个函数都是等价的 + fun returns_unit() {} + fun returns_2_values(): (bool, bool) { (true, false) } + fun returns_4_values(x: &u64): (&u64, u8, u128, vector) { (x, 0, 1, b"foobar") } + + fun examples(cond: bool) { + let () = (); + let (x, y): (u8, u64) = (0, 1); + let (a, b, c, d) = (@0x0, 0, false, b""); + + () = (); + (x, y) = if (cond) (1, 2) else (3, 4); + (a, b, c, d) = (@0x1, 1, true, b"1"); + } + + fun examples_with_function_calls() { + let () = returns_unit(); + let (x, y): (bool, bool) = returns_2_values(); + let (a, b, c, d) = returns_4_values(&0); + + () = returns_unit(); + (x, y) = returns_2_values(); + (a, b, c, d) = returns_4_values(&1); + } +} +} +``` + +有关更多详细信息,请参阅 [Move 变量](./variables.md)。 + +## 子类型 + +除了引用,元组是唯一在 Move 中具有[子类型(subtyping)](https://zh.wikipedia.org/wiki/%E5%AD%90%E7%B1%BB%E5%9E%8B)的类型。元组只有在具有引用的子类型(以协变方式)的意义上才具有子类型。 + +例如: + +```move +let x: &u64 = &0; +let y: &mut u64 = &mut 1; + +// (&u64, &mut u64) 是 (&u64, &u64) 的子类型 +// 因为 &mut u64 是 &u64 的子类型 +let (a, b): (&u64, &u64) = (x, y); + +// (&mut u64, &mut u64) 是 (&u64, &u64) 的子类型 +// 因为 &mut u64 是 &u64 的子类型 +let (c, d): (&u64, &u64) = (y, y); + +// 错误!(&u64, &mut u64) 不是 (&mut u64, &mut u64) 的子类型 +// 因为 &u64 不是 &mut u64 的子类型 +let (e, f): (&mut u64, &mut u64) = (x, y); +``` + +## 所有权 + +如上所述,元组值在运行时并不真正存在。由于这个原因,目前它们不能存储到局部变量中(但这个功能很可能很快就会出现)。因此,元组目前只能移动,因为复制它们需要先将它们放入局部变量中。 diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/unit-testing.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/unit-testing.md new file mode 100644 index 000000000..24f1fa5fc --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/unit-testing.md @@ -0,0 +1,367 @@ +# 单元测试 (Unit Tests) + +Unit testing for Move adds three new annotations to the Move source language: + +Move 语言中存在三种单元测试标注: + +* `#[test]` +* `#[test_only]`, and +* `#[expected_failure]`. + +They respectively mark a function as a test, mark a module or module member (`use`, function, or struct) as code to be included for testing only, and mark that a test is expected to fail. These annotations can be placed on a function with any visibility. Whenever a module or module member is annotated as `#[test_only]` or `#[test]`, it will not be included in the compiled bytecode unless it is compiled for testing. + +它们分别把函数、模块或模块成员(`use` 声明,函数 function,或结构体 struct)标记为只用于测试的代码,同时也标记期望失败的测试。这些标注可以用在任何可见性(visibility)函数上。无论何种情况,被标注为 `#[test_only]` 或 `#[test]` 的模块或模块成员除非用于测试,其它情况都不会被编译成字节码。 + +## 测试注解:含义和使用方法(Testing Annotations: Their Meaning and Usage) + +Both the `#[test]` and `#[expected_failure]` annotations can be used either with or without arguments. + +`#[test]` 和 `#[expected_failure]` 两个注解均可以在有、无参数情况下使用。 + +Without arguments, the `#[test]` annotation can only be placed on a function with no parameters. This annotation simply marks this function as a test to be run by the unit testing harness. + +没有参数的 `#[test]` 标记只能用于没有参数的函数。表示该函数作为单元测试函数被运行。 + +``` +#[test] // 正确 // OK +fun this_is_a_test() { ... } + +#[test] // 编译失败,因为函数需要参数 // Will fail to compile since the test takes an argument +fun this_is_not_correct(arg: signer) { ... } +``` + +A test can also be annotated as an `#[expected_failure]`. This annotation marks that the test should is expected to raise an error. You can ensure that a test is aborting with a specific abort code by annotating it with `#[expected_failure(abort_code = )]`, if it then fails with a different abort code or with a non-abort error the test will fail. Only functions that have the `#[test]` annotation can also be annotated as an #`[expected_failure]`. + +测试也可以使用 `#[expected_failure]` 标注,表示该函数会抛出错误。你可以使用 `#[expected_failure(abort_code = )]` 这种方式方式确保此测试会被指定错误码打断,如果抛出不同错误码或没有抛出错误测试将失败。只有被 `#[test]` 标注的函数才能使用 `#[expected_failure]` 标注。 + +``` +#[test] +#[expected_failure] +public fun this_test_will_abort_and_pass() { abort 1 } + +#[test] +#[expected_failure] +public fun test_will_error_and_pass() { 1/0; } + +#[test] +#[expected_failure(abort_code = 0)] +public fun test_will_error_and_fail() { 1/0; } + +#[test, expected_failure] // 可以合并多个属性。测试将会通过。 // Can have multiple in one attribute. This test will pass. +public fun this_other_test_will_abort_and_pass() { abort 1 } +``` + +With arguments, a test annotation takes the form `#[test( =
, ..., =
)]`. If a function is annotated in such a manner, the function's parameters must be a permutation of the parameters <`param_name_1>, ..., `, i.e., the order of these parameters as they occur in the function and their order in the test annotation do not have to be the same, but they must be able to be matched up with each other by name. + +测试标注可以采用 `#[test( =
, ..., =
)]` 这种形式指定参数。如果函数使用这样的标注,函数的参数则必须为 `, ..., ` 的形式。参数在函数中的顺序不必与注解中顺序一致,但必须要能根据参数名匹配。 + +Only parameters with a type of `signer` are supported as test parameters. If a non-`signer` parameter is supplied, the test will result in an error when run. + +只有 `signer` 类型可以用作测试参数。使用非 `signer` 类型参数,测试将会失败。 + +``` +#[test(arg = @0xC0FFEE)] // 正确 // OK +fun this_is_correct_now(arg: signer) { ... } + +#[test(wrong_arg_name = @0xC0FFEE)] // 不正确: 参数名不匹配 // Not correct: arg name doesn't match +fun this_is_incorrect(arg: signer) { ... } + +#[test(a = @0xC0FFEE, b = @0xCAFE)] // 正确,多参数情况下必须为每个参数提供值。 // OK. We support multiple signer arguments, but you must always provide a value for that argument +fun this_works(a: signer, b: signer) { ... } + +// 在某处声明一个命名地址(named address) // somewhere a named address is declared +#[test_only] // 命名地址支持 test-only 注解 // test-only named addresses are supported +address TEST_NAMED_ADDR = @0x1; +... +#[test(arg = @TEST_NAMED_ADDR)] // 支持命名地址! // Named addresses are supported! +fun this_is_correct_now(arg: signer) { ... } +``` + +An expected failure annotation can also take the form `#[expected_failure(abort_code = )]`. If a test function is annotated in such a way, the test must abort with an abort code equal to ``. Any other failure or abort code will result in a test failure. + +预期失败的标注使用 `#[expected_failure(abort_code = )]` 这种形式。如果函数被这样标注,测试错误码必须为 ``。任何其它的错误或错误码都会失败。 + +``` +#[test, expected_failure(abort_code = 1)] // 这个测试会失败 // This test will fail +fun this_test_should_abort_and_fail() { abort 0 } + +#[test] +#[expected_failure(abort_code = 0)] // 这个测试会通过 // This test will pass +fun this_test_should_abort_and_pass_too() { abort 0 } +``` + +A module and any of its members can be declared as test only. In such a case the item will only be included in the compiled Move bytecode when compiled in test mode. Additionally, when compiled outside of test mode, any non-test `use`s of a `#[test_only]` module will raise an error during compilation. + +模块和它的成员可以被声明为仅测试用。这种情况它们只会在测试模式下编译。此外,在非测试模式下,任何被 `#[test_only]` 标记的模块都会在编译时报错。 + +``` +#[test_only] // test only 属性可以用于模块 // test only attributes can be attached to modules +module abc { ... } + +#[test_only] // test only 属性可以用于命名地址 // test only attributes can be attached to named addresses +address ADDR = @0x1; + +#[test_only] // .. 用于 use 声明 // .. to uses +use 0x1::some_other_module; + +#[test_only] // .. 用于结构体 // .. to structs +struct SomeStruct { ... } + +#[test_only] // .. 用于函数。只能在测试函数中调用,但自身不是测试 // .. and functions. Can only be called from test code, but not a test +fun test_only_function(...) { ... } +``` + +## 运行单元测试(Running Unit Tests) + +Unit tests for a Move package can be run with the [`move test` +command](./packages.md). + +使用 [`move test` 命令](./packages.md)运行包中的单元测试。 + +When running tests, every test will either `PASS`, `FAIL`, or `TIMEOUT`. If a test case fails, the location of the failure along with the function name that caused the failure will be reported if possible. You can see an example of this below. + +运行测试的结果包括 `PASS`、`FAIL` 或 `TIMEOUT`。如果测试失败,将会尽可能的提供执行失败的位置及函数名信息。请看下面的例子。 + +A test will be marked as timing out if it exceeds the maximum number of instructions that can be executed for any single test. This bound can be changed using the options below, and its default value is set to 5000 instructions. Additionally, while the result of a test is always deterministic, tests are run in parallel by default, so the ordering of test results in a test run is non-deterministic unless running with only one thread (see `OPTIONS` below). + +任何测试执行超过最大数量指令限制将会标记成超时。可以通过参数调整此限制,默认值为 5000 条指令。此外,虽然测试结果是确定的,但由于测试默认并行执行,所以测试结果的顺序是不确定的,除非使用单线程模式(见下述参数)。 + +There are also a number of options that can be passed to the unit testing binary to fine-tune testing and to help debug failing tests. These can be found using the the help flag: + +存在大量参数细粒度调整测试工具的行为,帮助调试失败的测试。可以通过 help 参数查看。 + +``` +$ move -h +``` + +## 示例(Example) + +A simple module using some of the unit testing features is shown in the following example: + +下面例子展示了一个简单的使用了单元测试特性的模块: + +First create an empty package and change directory into it: + +首先创建一个空 package 进入目录: + +``` +$ move new TestExample; cd TestExample +``` + +Next add the following to the `Move.toml`: + +接下来添加下面内容到 `Move.toml` 文件: + +``` +[dependencies] +MoveStdlib = { git = "https://github.com/diem/diem.git", subdir="language/move-stdlib", rev = "56ab033cc403b489e891424a629e76f643d4fb6b", addr_subst = { "std" = "0x1" } } +``` + +Next add the following module under the `sources` directory: + +接下来在 `sources` 目录下添加下述模块: + +``` +// 文件路径: sources/my_module.move // filename: sources/my_module.move +module 0x1::my_module { + + struct MyCoin has key { value: u64 } + + public fun make_sure_non_zero_coin(coin: MyCoin): MyCoin { + assert!(coin.value > 0, 0); + coin + } + + public fun has_coin(addr: address): bool { + exists(addr) + } + + #[test] + fun make_sure_non_zero_coin_passes() { + let coin = MyCoin { value: 1 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test] + // 如果不关心错误码也可以使用 #[expected_failure] // Or #[expected_failure] if we don't care about the abort code + #[expected_failure(abort_code = 0)] + fun make_sure_zero_coin_fails() { + let coin = MyCoin { value: 0 }; + let MyCoin { value: _ } = make_sure_non_zero_coin(coin); + } + + #[test_only] // 仅用作测试的帮助方法 // test only helper function + fun publish_coin(account: &signer) { + move_to(account, MyCoin { value: 1 }) + } + + #[test(a = @0x1, b = @0x2)] + fun test_has_coin(a: signer, b: signer) { + publish_coin(&a); + publish_coin(&b); + assert!(has_coin(@0x1), 0); + assert!(has_coin(@0x2), 1); + assert!(!has_coin(@0x3), 1); + } +} +``` + +### 运行测试(Running Tests) + +You can then run these tests with the `move test` command: + +你可以使用 `move test` 命令运行测试。 + +``` +$ move test +BUILDING MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +[ PASS ] 0x1::my_module::test_has_coin +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +### 使用测试参数(Using Test Flags) + +#### `-f ` 或 `--filter `(`-f ` or `--filter `) + +This will only run tests whose fully qualified name contains ``. For example if we wanted to only run tests with `"zero_coin"` in their name: + +仅运行名字包含 `` 字符的测试。例如只想运行名字包含 `"zero_coin"` 的测试: + + +``` +$ move test -f zero_coin +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +Test result: OK. Total tests: 2; passed: 2; failed: 0 +``` + +#### `-i ` 或 `--gas_used `(`-i ` or `--gas_used `) + +This bounds the amount of gas that can be consumed for any one test to ``: + +调整测试指令限制为 ``: + +``` +$ move test -i 0 +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ TIMEOUT ] 0x1::my_module::make_sure_non_zero_coin_passes +[ TIMEOUT ] 0x1::my_module::make_sure_zero_coin_fails +[ TIMEOUT ] 0x1::my_module::test_has_coin + +Test failures: + +Failures in 0x1::my_module: + +┌── make_sure_non_zero_coin_passes ────── +│ Test timed out +└────────────────── + + +┌── make_sure_zero_coin_fails ────── +│ Test timed out +└────────────────── + + +┌── test_has_coin ────── +│ Test timed out +└────────────────── + +Test result: FAILED. Total tests: 3; passed: 0; failed: 3 +``` + +#### `-s` 或 `--statistics`(`-s` or `--statistics`) + +With these flags you can gather statistics about the tests run and report the runtime and gas used for each test. For example, if we wanted to see the statistics for the tests in the example above: + +使用此参数你可以得到每个测试的运行报告及执行指令的统计信息。例如查看上述示例的统计数据: + +``` +$ move test -s +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +[ PASS ] 0x1::my_module::test_has_coin + +Test Statistics: + +┌────────────────────────────────────────────────┬────────────┬───────────────────────────┐ +│ Test Name │ Time │ Gas Used │ +├────────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::my_module::make_sure_non_zero_coin_passes │ 0.009 │ 1 │ +├────────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::my_module::make_sure_zero_coin_fails │ 0.008 │ 1 │ +├────────────────────────────────────────────────┼────────────┼───────────────────────────┤ +│ 0x1::my_module::test_has_coin │ 0.008 │ 1 │ +└────────────────────────────────────────────────┴────────────┴───────────────────────────┘ + +Test result: OK. Total tests: 3; passed: 3; failed: 0 +``` + +#### `-g` 或 `--state-on-error`(`-g` or `--state-on-error`) + +These flags will print the global state for any test failures. e.g., if we added the following (failing) test to the `my_module` example: + +这个参数会在测试失败情况下打印全局状态。如在 `my_module` 模块中添加下述失败测试: + +``` +module 0x1::my_module { + ... + #[test(a = @0x1)] + fun test_has_coin_bad(a: signer) { + publish_coin(&a); + assert!(has_coin(@0x1), 0); + assert!(has_coin(@0x2), 1); + } +} +``` + +we would get get the following output when running the tests: + +当运行测试时我们将得到下面的输出: + +``` +$ move test -g +CACHED MoveStdlib +BUILDING TestExample +Running Move unit tests +[ PASS ] 0x1::my_module::make_sure_non_zero_coin_passes +[ PASS ] 0x1::my_module::make_sure_zero_coin_fails +[ PASS ] 0x1::my_module::test_has_coin +[ FAIL ] 0x1::my_module::test_has_coin_bad + +Test failures: + +Failures in 0x1::my_module: + +┌── test_has_coin_bad ────── +│ error[E11001]: test failure +│ ┌─ /home/tzakian/TestExample/sources/my_module.move:47:10 +│ │ +│ 44 │ fun test_has_coin_bad(a: signer) { +│ │ ----------------- In this function in 0x1::my_module +│ · +│ 47 │ assert!(has_coin(@0x2), 1); +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to abort but it aborted with 1 here +│ +│ +│ ────── Storage state at point of failure ────── +│ 0x1: +│ => key 0x1::my_module::MyCoin { +│ value: 1 +│ } +│ +└────────────────── + +Test result: FAILED. Total tests: 4; passed: 3; failed: 1 +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/uses.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/uses.md new file mode 100644 index 000000000..79918badf --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/uses.md @@ -0,0 +1,376 @@ +# 使用与别名(Uses and Aliases) + +The `use` syntax can be used to create aliases to members in other modules. `use` can be used to +create aliases that last either for the entire module, or for a given expression block scope. + +`use` 语法可用于为其他模块中的成员创建别名。 `use` 可用于创建持续整个模块或给定表达式块范围的别名。 + +## 语法(Syntax) +There are several different syntax cases for `use`. Starting with the most simple, we have the +following for creating aliases to other modules + +这里有几种不同的语法案例可供使用。从最简单的开始,我们有以下例子用于为其他模块创建别名 + +```move +use
::; +use
:: as ; +``` +For example +举例 +```move +use std::vector; +use std::vector as V; +``` + +`use std::vector;` introduces an alias `vector` for `std::vector`. This means that anywhere you +would want to use the module name `std::vector` (assuming this `use` is in scope), you could use +`vector` instead. `use std::vector;` is equivalent to `use std::vector as vector;` + +`use std::vector;`为 `std::vector` 引入别名向量。这意味着在任何您想使用模块名称 `std::vector` 的地方(假设此`use`在作用域内),您都可以使用 `vector` 代替使用`std::vector`; + +Similarly `use std::vector as V;` would let you use `V` instead of `std::vector` + +同样使用 `std::vector as V`;会让你使用 `V` 代替 `std::vector` + +```move +use std::vector; +use std::vector as V; + +fun new_vecs(): (vector, vector, vector) { + let v1 = std::vector::empty(); + let v2 = vector::empty(); + let v3 = V::empty(); + (v1, v2, v3) +} +``` +If you want to import a specific module member (such as a function, struct, or constant). You can +use the following syntax. + +如果要导入特定的模块成员(例如函数、结构或常量)。您可以使用以下语法。 +```move +use
::::; +use
:::: as ; +``` +For example +举例 + +```move +use std::vector::empty; +use std::vector::empty as empty_vec; +``` + +This would let you use the function `std::vector::empty` without full qualification. Instead you +could use `empty` and `empty_vec` respectively. Again, `use std::vector::empty;` is equivalent to +`use std::vector::empty as empty;` + +这将允许您在没有前缀限定的情况下使用函数 `std::vector::empty`。相反,您可以分别使用 `empty` 和 `empty_vec`,使用 `std::vector::empty;`使用`empty` 相当于使用`std::vector::empty`; + +```move +use std::vector::empty; +use std::vector::empty as empty_vec; + +fun new_vecs(): (vector, vector, vector) { + let v1 = std::vector::empty(); + let v2 = empty(); + let v3 = empty_vec(); + (v1, v2, v3) +} +``` +If you want to add aliases for multiple module members at once, you can do so with the following +syntax + +如果要一次为多个模块成员添加别名,可以使用以下语法 +```move +use
::::{, as ... }; +``` +For example +举例 + +```move +use std::vector::{push_back, length as len, pop_back}; + +fun swap_last_two(v: &mut vector) { + assert!(len(v) >= 2, 42); + let last = pop_back(v); + let second_to_last = pop_back(v); + push_back(v, last); + push_back(v, second_to_last) +} +``` + +If you need to add an alias to the Module itself in addition to module members, you can do that in a +single `use` using `Self`. `Self` is a member of sorts that refers to the module. + +如果除了模块成员之外,您还需要为模块本身添加别名,您可以使用 `Self` 在一次`use`中完成。 `Self` 是指模块的各种成员。 +```move +use std::vector::{Self, empty}; +For clarity, all of the following are equivalent: +``` +For clarity, all of the following are equivalent: + +为清晰起见,以下所有内容都是等效的: +```move +use std::vector; +use std::vector as vector; +use std::vector::Self; +use std::vector::Self as vector; +use std::vector::{Self}; +use std::vector::{Self as vector}; +``` +If needed, you can have as many aliases for any item as you like + +如果需要,您可以为任何项目设置任意数量的别名 + +```move +use std::vector::{ + Self, + Self as V, + length, + length as len, +}; + +fun pop_twice(v: &mut vector): (T, T) { + // all options available given the `use` above + assert!(vector::length(v) > 1, 42); + assert!(V::length(v) > 1, 42); + assert!(length(v) > 1, 42); + assert!(len(v) > 1, 42); + + (vector::pop_back(v), vector::pop_back(v)) +} +``` + +## 模块内部(Inside a `module`) +Inside of a `module` all `use` declarations are usable regardless of the order of declaration. + +在模块内部,无论声明顺序如何,所有 `use` 声明都是可用的。 +```move +address 0x42 { +module example { + use std::vector; + + fun example(): vector { + let v = empty(); + vector::push_back(&mut v, 0); + vector::push_back(&mut v, 10); + v + } + + use std::vector::empty; +} +} +``` +The aliases declared by `use` in the module usable within that module. + +在该模块中可用的模块中使用声明的别名。 + +Additionally, the aliases introduced cannot conflict with other module members. See +[Uniqueness](#uniqueness) for more details + +此外,引入的别名不能与其他模块成员冲突。有关详细信息,请参阅[唯一性](#uniqueness)。 + +## 表达式内部(Inside an expression) +You can add `use` declarations to the beginning of any expression block + +您可以将 `use` 声明添加到任何表达式块的开头 +```move +address 0x42 { +module example { + + fun example(): vector { + use std::vector::{empty, push_back}; + + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 10); + v + } +} +} +``` +As with `let`, the aliases introduced by `use` in an expression block are removed at the end of that +block. + +与 `let` 一样,在表达式块中使用 `use` 引入的别名在该块的末尾被删除。 + +```move +address 0x42 { +module example { + + fun example(): vector { + let result = { + use std::vector::{empty, push_back}; + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 10); + v + }; + result + } + +} +} +``` +Attempting to use the alias after the block ends will result in an error + +在块结束后尝试使用别名将导致错误 +```move +fun example(): vector { + let result = { + use std::vector::{empty, push_back}; + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 10); + v + }; + let v2 = empty(); // 错误! +// ^^^^^ 未绑定的函数 'empty' + 结果 +} +``` +Any `use` must be the first item in the block. If the `use` comes after any expression or `let`, it +will result in a parsing error + +任何使用都必须是块中的第一项。如果 use 出现在任何表达式或 let 之后,则会导致解析错误 +```move +{ + let x = 0; + use std::vector; // 错误! + let v = vector::empty(); +} +``` + +## 命名规则(Naming rules) +Aliases must follow the same rules as other module members. This means that aliases to structs or +constants must start with `A` to `Z` + +别名必须遵循与其他模块成员相同的规则。这意味着结构或常量的别名必须以 `A` 到 `Z` 开头 +```move +address 0x42 { +module data { + struct S {} + const FLAG: bool = false; + fun foo() {} +} +module example { + use 0x42::data::{ + S as s, // 错误! + FLAG as fLAG, // 错误! + foo as FOO, // 有效 + foo as bar, // 有效 + }; +} +} +``` +## 唯一性(Uniqueness) +Inside a given scope, all aliases introduced by `use` declarations must be unique. + +在给定范围内,所有由 use 声明引入的别名必须是唯一的。 + +For a module, this means aliases introduced by `use` cannot overlap + +对于一个模块,这意味着使用引入的别名不能重复 +```move +address 0x42 { +module example { + + use std::vector::{empty as foo, length as foo}; // ERROR! + // ^^^ duplicate 'foo' + + use std::vector::empty as bar; + + use std::vector::length as bar; // 错误! + // ^^^ 重复的 'bar' + +} +} +``` +And, they cannot overlap with any of the module's other members + +而且,它们不能与模块的任何其他成员重复 +```move +address 0x42 { +module data { + struct S {} +} +module example { + use 0x42::data::S; + + struct S { value: u64 } // ERROR! + // ^ conflicts with alias 'S' above +} +} +``` +Inside of an expression block, they cannot overlap with each other, but they can +[shadow](#shadowing) other aliases or names from an outer scope + +在表达式块内部,它们不能相互重复,但它们可以遮蔽外部作用域中的其他别名或名称 + +## 遮蔽(Shadowing) +`use` aliases inside of an expression block can shadow names (module members or aliases) from the +outer scope. As with shadowing of locals, the shadowing ends at the end of the expression block; + +在表达式块内使用别名可以覆盖外部作用域的名称(模块成员或别名)。当遮蔽局部变量时,遮蔽会在表达式块的末尾结束; +```move +address 0x42 { +module example { + + struct WrappedVector { vec: vector } + + fun empty(): WrappedVector { + WrappedVector { vec: std::vector::empty() } + } + + fun example1(): (WrappedVector, WrappedVector) { + let vec = { + use std::vector::{empty, push_back}; + // 'empty' 现在指向 std::vector::empty + + let v = empty(); + push_back(&mut v, 0); + push_back(&mut v, 1); + push_back(&mut v, 10); + v + }; + // 'empty' 现在指向 Self::empty + + (empty(), WrappedVector { vec }) + } + + fun example2(): (WrappedVector, WrappedVector) { + use std::vector::{empty, push_back}; + let w: WrappedVector = { + use 0x42::example::empty; + empty() + }; + push_back(&mut w.vec, 0); + push_back(&mut w.vec, 1); + push_back(&mut w.vec, 10); + + let vec = empty(); + push_back(&mut vec, 0); + push_back(&mut vec, 1); + push_back(&mut vec, 10); + + (w, WrappedVector { vec }) + } +} +} +``` + +## 未使用的Use或别名(Unused Use or Alias) +An unused `use` will result in an error + +未使用的 `use` 会导致错误 +```move +address 0x42 { +module example { + use std::vector::{empty, push_back}; // ERROR! + // ^^^^^^^^^ 未使用的别名 'push_back' + + fun example(): vector { + empty() + } +} +} +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/variables.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/variables.md new file mode 100644 index 000000000..3625728ef --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/variables.md @@ -0,0 +1,879 @@ +# 局部变量和作用域(Local Variables and Scopes) + +Local variables in Move are lexically (statically) scoped. New variables are introduced with the +keyword `let`, which will shadow any previous local with the same name. Locals are mutable and can +be updated both directly and via a mutable reference. + +在 Move 语言中,局部变量的解析依赖于词法作用域(lexically scoped)或静态作用域(statically scoped)。使用关键字 `let` 引入新的变量,它将隐藏任何以前的同名局部变量。局部变量是可变的(Rust 中的变量默认不可变,译者注),可以直接更新,也可以通过可变引用更新。 + +## 声明局部变量(Declaring Local Variables) + +### `let` 绑定(`let` bindings) + +Move programs use `let` to bind variable names to values: + +Move 程序使用 `let` 给变量名绑定一个值: + +```move +let x = 1; +let y = x + x: +``` + +`let` can also be used without binding a value to the local. + +`let` 使用时也可以不绑定任何数值给局部变量。 + +```move +let x; +``` + +The local can then be assigned a value later. + +然后可以稍后为局部变量赋一个值。 + +```move +let x; +if (cond) { + x = 1 +} else { + x = 0 +} +``` + +This can be very helpful when trying to extract a value from a loop when a default value cannot be provided. + +当无法提供默认值时,这在尝试从循环中提取值时非常有用。 + +```move +let x; +let cond = true; +let i = 0; +loop { + (x, cond) = foo(i); + if (!cond) break; + i = i + 1; +} +``` + +### 变量必须在使用前赋值(Variables must be assigned before use) + +Move's type system prevents a local variable from being used before it has been assigned. + +Move 的类型系统防止在赋值之前使用局部变量。 + +```move +let x; +x + x // ERROR! +``` + +```move +let x; +if (cond) x = 0; +x + x // ERROR! +``` + +```move +let x; +while (cond) x = 0; +x + x // ERROR! +``` + +### 有效的变量名(Valid variable names) + +Variable names can contain underscores `_`, letters `a` to `z`, letters `A` to `Z`, and digits `0` +to `9`. Variable names must start with either an underscore `_` or a letter `a` through `z`. They +_cannot_ start with uppercase letters. + +变量名可以包含下划线 `_`、小写字母 `a` 到 `z`、大写字母 `A` 到 `Z`、和数字 `0` 到 `9`。变量名必须以下划线 `_` 或者以小写字母`a`到`z`开头。它们*不能*以大写字母开头。 + +```move +// 全部有效 +let x = e; +let _x = e; +let _A = e; +let x0 = e; +let xA = e; +let foobar_123 = e; + +// 全部无效 +let X = e; // ERROR! +let Foo = e; // ERROR! +``` + +### 类型标注(Type annotations) + +The type of a local variable can almost always be inferred by Move's type system. However, Move +allows explicit type annotations that can be useful for readability, clarity, or debuggability. The +syntax for adding a type annotation is: + +局部变量的类型几乎总是可以通过 Move 的类型系统推断出来。但是,Move 允许显式类型标注,这对可读性、清晰性或可调试性很有用。添加类型标注的语法如下: + +```move +let x: T = e; // “T 类型的变量 x 被初始化为表达式 e” +``` + +Some examples of explicit type annotations: + +一些显式类型标注的示例: + +```move +address 0x42 { +module example { + + struct S { f: u64, g: u64 } + + fun annotated() { + let u: u8 = 0; + let b: vector = b"hello"; + let a: address = @0x0; + let (x, y): (&u64, &mut u64) = (&0, &mut 1); + let S { f, g: f2 }: S = S { f: 0, g: 1 }; + } +} +} +``` + +Note that the type annotations must always be to the right of the pattern: + +请注意,类型标注必须始终位于变量模式的右侧: + +```move +let (x: &u64, y: &mut u64) = (&0, &mut 1); // 错误!正确写法是 let (x, y): ... = +``` + +### 何时需要类型标注(When annotations are necessary) + +In some cases, a local type annotation is required if the type system cannot infer the type. This +commonly occurs when the type argument for a generic type cannot be inferred. For example: + +在某些情况下,如果类型系统无法推断类型,则需要局部类型标注。这通常发生在无法推断某个泛型(generic type)的类型参数时,比如: + +```move +let _v1 = vector::empty(); // 错误! +// ^^^^^^^^^^^^^^^ Could not infer this type. Try adding an annotation (无法推断此类型。尝试添加标注) +let v2: vector = vector::empty(); // 没有错误 +``` + +In a rarer case, the type system might not be able to infer a type for divergent code (where all the +following code is unreachable). Both `return` and [`abort`](./abort-and-assert.md) are expressions +and can have any type. A [`loop`](./loops.md) has type `()` if it has a `break`, but if there is no +break out of the `loop`, it could have any type. If these types cannot be inferred, a type +annotation is required. For example, this code: + +在极少数情况下,Move 的类型系统可能无法推断出一段发散式代码(divergent code)的类型(后面所有代码无法访问)。在 Move 语言中,`return` 和 [`abort`](./abort-and-assert.md) 都属于表达式,它们可以返回任何类型。如果一段 [`loop`](./loops.md) 有 `break`,那么它的返回类型是 `()`,但是如果它不包含 `break`,它的返回类型可以是任何类型。如果无法推断出这些类型,那么类型标注是必须的。例如,这段代码: + +```move +let a: u8 = return (); +let b: bool = abort 0; +let c: signer = loop (); + +let x = return (); // ERROR! +// ^ Could not infer this type. Try adding an annotation +let y = abort 0; // ERROR! +// ^ Could not infer this type. Try adding an annotation +let z = loop (); // ERROR! +// ^ Could not infer this type. Try adding an annotation +``` + +Adding type annotations to this code will expose other errors about dead code or unused local +variables, but the example is still helpful for understanding this problem. + +在这段代码中添加类型标注会暴露其他关于死代码或未使用的局部变量的错误,但该示例仍然有助于理解这个问题。 + +### 元组式的多个变量声明(Multiple declarations with tuples) + +`let` can introduce more than one local at a time using tuples. The locals declared inside the +parenthesis are initialized to the corresponding values from the tuple. + +`let` 可以使用元组一次引入多个局部变量。在括号内声明的局部变量会被初始化为元组中的对应值。 + +```move +let () = (); +let (x0, x1) = (0, 1); +let (y0, y1, y2) = (0, 1, 2); +let (z0, z1, z2, z3) = (0, 1, 2, 3); +``` + +The type of the expression must match the arity of the tuple pattern exactly. + +表达式的类型必须与元组模式的数量完全匹配。 + +```move +let (x, y) = (0, 1, 2); // 错误! +let (x, y, z, q) = (0, 1, 2); // 错误! +``` + +You cannot declare more than one local with the same name in a single `let`. + +你不能在单个 `let` 中声明多个具有相同名称的局部变量。 + +```move +let (x, x) = 0; // 错误! +``` + +### 结构体式的多个变量声明(Multiple declarations with structs) + +`let` can also introduce more than one local at a time when destructuring (or matching against) a +struct. In this form, the `let` creates a set of local variables that are initialized to the values +of the fields from a struct. The syntax looks like this: + +`let` 还可以在解构(或匹配)结构体时一次引入多个局部变量。在这种形式中,`let` 创建了一组局部变量,这些变量被初始化为结构体中字段的值。语法如下所示: + +```move +struct T { f1: u64, f2: u64 } +``` + +```move +let T { f1: local1, f2: local2 } = T { f1: 1, f2: 2 }; +// local1: u64 +// local2: u64 +``` + +Here is a more complicated example: + +这是一个更复杂的示例: + +```move +address 0x42 { + module example { + struct X { f: u64 } + struct Y { x1: X, x2: X } + + fun new_x(): X { + X { f: 1 } + } + + fun example() { + let Y { x1: X { f }, x2 } = Y { x1: new_x(), x2: new_x() }; + assert!(f + x2.f == 2, 42); + + let Y { x1: X { f: f1 }, x2: X { f: f2 } } = Y { x1: new_x(), x2: new_x() }; + assert!(f1 + f2 == 2, 42); + } + } +} +``` + +Fields of structs can serve double duty, identifying the field to bind _and_ the name of the +variable. This is sometimes referred to as punning. + +结构体的字段可以起到双重作用:识别要绑定的字段*和*命名变量。这有时被称为双关语。 + +```move +let X { f } = e; +``` + +is equivalent to: + +等价于: + +```move +let X { f: f } = e; +``` + +As shown with tuples, you cannot declare more than one local with the same name in a single `let`. + +如元组所示,您不能在单个 `let` 中声明多个具有相同名称的局部变量。 + +```move +let Y { x1: x, x2: x } = e; // 错误!(两个 x 同名了) +``` + +### 针对引用进行解构(Destructuring against references) + +In the examples above for structs, the bound value in the let was moved, destroying the struct value +and binding its fields. + +在上面的结构体示例中,`let` 中绑定的值被移动了,这销毁了结构体的值并同时绑定了它的字段(到变量)。 + +```move +struct T { f1: u64, f2: u64 } +``` + +```move +let T { f1: local1, f2: local2 } = T { f1: 1, f2: 2 }; +// local1: u64 +// local2: u64 +``` + +In this scenario the struct value `T { f1: 1, f2: 2 }` no longer exists after the `let`. + +If you wish instead to not move and destroy the struct value, you can borrow each of its fields. For +example: + +在这种场景下结构体的值 `T { f1: 1, f2: 2 }` 会在 `let` 后消失。 + +如果您希望不移动和销毁结构体的值,则可以借用其中的每个字段。例如: + +```move +let t = T { f1: 1, f2: 2 }; +let T { f1: local1, f2: local2 } = &t; +// local1: &u64 +// local2: &u64 +``` + +And similarly with mutable references: + +可变引用也类似: + +```move +let t = T { f1: 1, f2: 2 }; +let T { f1: local1, f2: local2 } = &mut t; +// local1: &mut u64 +// local2: &mut u64 +``` + +This behavior can also work with nested structs. + +此行为也适用于嵌套结构体。 + +```move +address 0x42 { + module example { + struct X { f: u64 } + struct Y { x1: X, x2: X } + + fun new_x(): X { + X { f: 1 } + } + + fun example() { + let y = Y { x1: new_x(), x2: new_x() }; + + let Y { x1: X { f }, x2 } = &y; + assert!(*f + x2.f == 2, 42); + + let Y { x1: X { f: f1 }, x2: X { f: f2 } } = &mut y; + *f1 = *f1 + 1; + *f2 = *f2 + 1; + assert!(*f1 + *f2 == 4, 42); + } + } +} +``` + +### 忽略值(Ignoring Values) + +In `let` bindings, it is often helpful to ignore some values. Local variables that start with `_` +will be ignored and not introduce a new variable + +在 `let` 绑定中,忽略某些值通常很有帮助。以 `_` 开头的局部变量将被忽略并且不会引入新变量。 + +```move +fun three(): (u64, u64, u64) { + (0, 1, 2) +} +``` + +```move +let (x1, _, z1) = three(); +let (x2, _y, z2) = three(); +assert!(x1 + z1 == x2 + z2, 42); +``` + +This can be necessary at times as the compiler will error on unused local variables。 + +这有时是必要的,因为编译器会在未使用的局部变量上报错。 + +```move +let (x1, y, z1) = three(); // 错误! +// ^ 未被使用的局部变量 'y' +``` + +### 通用的 `let` 语法(General `let` grammar) + +All of the different structures in `let` can be combined! With that we arrive at this general +grammar for `let` statements: + +`let` 中所有不同的结构体都可以组合!这样,我们就得出了 `let` 语句的通用语法: + +> _let-binding_ → **let** _pattern-or-list_ _type-annotation__opt_ +> _initializer__opt_ > _pattern-or-list_ → _pattern_ | **(** _pattern-list_ **)** > +> _pattern-list_ → _pattern_ **,**_opt_ | _pattern_ **,** _pattern-list_ > +> _type-annotation_ → **:** _type_ _initializer_ → **=** _expression_ + +The general term for the item that introduces the bindings is a _pattern_. The pattern serves to +both destructure data (possibly recursively) and introduce the bindings. The pattern grammar is as +follows: + +引入绑定的项的通用术语是 *模式(pattern)*。该模式用于解构数据(可能是递归的)并引入绑定。模式语法如下: + +> _pattern_ → _local-variable_ | _struct-type_ **{** _field-binding-list_ **}** > +> _field-binding-list_ → _field-binding_ **,**_opt_ | _field-binding_ **,** +> _field-binding-list_ > _field-binding_ → _field_ | _field_ **:** _pattern_ + +A few concrete examples with this grammar applied: + +应用此语法的一些具体示例: + +```move + let (x, y): (u64, u64) = (0, 1); +// ^ local-variable(局部变量) +// ^ pattern(模式) +// ^ local-variable(局部变量) +// ^ pattern(模式) +// ^ pattern-list(模式列表) +// ^^^^ pattern-list(模式列表) +// ^^^^^^ pattern-or-list(模式或列表) +// ^^^^^^^^^^^^ type-annotation(类型标注) +// ^^^^^^^^ initializer(初始化器) +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ let-binding(let 绑定) + + let Foo { f, g: x } = Foo { f: 0, g: 1 }; +// ^^^ struct-type(结构类型) +// ^ field(字段) +// ^ field-binding(字段绑定) +// ^ field(字段) +// ^ local-variable(局部变量) +// ^ pattern(模式) +// ^^^^ field-binding(字段绑定) +// ^^^^^^^ field-binding-list(字段绑定列表) +// ^^^^^^^^^^^^^^^ pattern(模式) +// ^^^^^^^^^^^^^^^ pattern-or-list(模式或列表) +// ^^^^^^^^^^^^^^^^^^^^ initializer(初始化器) +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ let-binding(let 绑定) +``` + +## 变更(Mutations) + +### 赋值(Assignments) + +After the local is introduced (either by `let` or as a function parameter), the local can be +modified via an assignment: + +在引入局部变量后(通过 `let` 或作为函数参数),可以通过赋值来修改局部变量: + +```move +x = e +``` + +Unlike `let` bindings, assignments are expressions. In some languages, assignments return the value +that was assigned, but in Move, the type of any assignment is always `()`. + +与 `let` 绑定不同,赋值是表达式。在某些语言中,赋值会返回被赋予的值,但在 Move 语言中,任何赋值的返回类型始终是 `()`。 + +```move +(x = e: ()) +``` + +Practically, assignments being expressions means that they can be used without adding a new +expression block with braces (`{`...`}`). + +实际上,赋值作为表达式意味着它们可以在不添加带有大括号(`{`...`}`)的新表达式块(expression block)的情况下使用。 + +```move +let x = 0; +if (cond) x = 1 else x = 2; +``` + +The assignment uses the same pattern syntax scheme as `let` bindings: + +赋值使用与 `let` 绑定相同的模式语法方案: + +```move +address 0x42 { +module example { + struct X { f: u64 } + + fun new_x(): X { + X { f: 1 } + } + + // 这个例子会因为存在未使用的变量和赋值而报错。 + fun example() { + let (x, _, z) = (0, 1, 3); + let (x, y, f, g); + + (X { f }, X { f: x }) = (new_x(), new_x()); + assert!(f + x == 2, 42); + + (x, y, z, f, _, g) = (0, 0, 0, 0, 0, 0); + } +} +} +``` + +Note that a local variable can only have one type, so the type of the local cannot change between +assignments. + +注意,一个局部变量只能有一种类型,所以局部变量的类型不能在赋值之间(多次赋值)改变。 + +```move +let x; +x = 0; +x = false; // 错误! +``` + +### 通过引用进行变更(Mutating through a reference) + +In addition to directly modifying a local with assignment, a local can be modified via a mutable +reference `&mut`. + +除了通过赋值直接修改局部变量外,还可以通过可变引用 `&mut` 的方式修改局部变量。 + +```move +let x = 0; +let r = &mut x; +*r = 1; +assert!(x == 1, 42); +``` + +This is particularly useful if either: + +(1) You want to modify different variables depending on some condition. + +这在以下情况下特别有用: + +(1) 你想根据某些条件修改不同的变量。 + +```move +let x = 0; +let y = 1; +let r = if (cond) &mut x else &mut y; +*r = *r + 1; +``` + +(2) You want another function to modify your local value. + +(2) 你想要另一个函数来修改你的局部变量值。 + +```move +let x = 0; +modify_ref(&mut x); +``` + +This sort of modification is how you modify structs and vectors! + +这种修改方法就是你修改结构体和向量的方式! + +```move +let v = vector::empty(); +vector::push_back(&mut v, 100); +assert!(*vector::borrow(&v, 0) == 100, 42); +``` + +For more details, see [Move references](./references.md). + +有关更多详细信息,请参阅 [Move 引用](./references.md)。 + +## 作用域(Scopes) + +Any local declared with `let` is available for any subsequent expression, _within that scope_. +Scopes are declared with expression blocks, `{`...`}`. + +Locals cannot be used outside of the declared scope. + +使用 `let` 声明的任何局部变量都可用于*该作用域内*的任何后续表达式。作用域用表达式块(expression blocks)声明,`{`...`}`。 + +局部变量不能在声明的作用域之外使用。 + +```move +let x = 0; +{ + let y = 1; +}; +x + y // 错误! +// ^ unbound local 'y'(未绑定的局部变量“y”) +``` + +But, locals from an outer scope _can_ be used in a nested scope. + +但是,来自外部作用域的本地变量*可以*在嵌套作用域中使用。 + +```move +{ + let x = 0; + { + let y = x + 1; // 有效的 + } +} +``` + +Locals can be mutated in any scope where they are accessible. That mutation survives with the local, +regardless of the scope that performed the mutation. + +局部变量可以在允许访问的任何作用域内进行变更。无论执行变更的作用域如何,这种变更会跟随局部变量的生命周期。 + +```move +let x = 0; +x = x + 1; +assert!(x == 1, 42); +{ + x = x + 1; + assert!(x == 2, 42); +}; +assert!(x == 2, 42); +``` + +### 表达式块(Expression Blocks) + +An expression block is a series of statements separated by semicolons (`;`). The resulting value of +an expression block is the value of the last expression in the block. + +表达式块是由分号(`;`)分隔的一系列语句。表达式块的结果值是块中最后一个表达式的值。 + +```move +{ let x = 1; let y = 1; x + y } +``` + +In this example, the result of the block is `x + y`. + +A statement can be either a `let` declaration or an expression. Remember that assignments (`x = e`) +are expressions of type `()`. + +在此示例中, 此区块的结果是 `x + y`. + +语句可以是 `let` 声明或表达式。请记住,赋值(`x = e`)是 `()` 类型的表达式。 + +```move +{ let x; let y = 1; x = 1; x + y } +``` + +Function calls are another common expression of type `()`. Function calls that modify data are +commonly used as statements. + +函数调用是 `()` 类型的另一种常见表达方式。修改数据的函数调用通常被用作语句。 + +```move +{ let v = vector::empty(); vector::push_back(&mut v, 1); v } +``` + +This is not just limited to `()` types---any expression can be used as a statement in a sequence! + +这不仅限于 `()` 类型 —— 任何表达式都可以用作序列中的语句! + +```move +{ + let x = 0; + x + 1; // 值会被丢弃 + x + 2; // 值会被丢弃 + b"hello"; // 值会被丢弃 +} +``` + +But! If the expression contains a resource (a value without the `drop` [ability](./abilities.md)), +you will get an error. This is because Move's type system guarantees that any value that is dropped +has the `drop` [ability](./abilities.md). (Ownership must be transferred or the value must be +explicitly destroyed within its declaring module.) + +但是!如果表达式包含资源(没有 `drop` [能力](./abilities.md)的值),你将收到错误消息。这是因为 Move 的类型系统保证任何被删除的值都具有 `drop` [能力](./abilities.md)。(必须转移所有权,或者必须在其声明模块中显式销毁该值。) + +```move +{ + let x = 0; + Coin { value: x }; // 错误! +// ^^^^^^^^^^^^^^^^^ unused value without the `drop` ability(未使用没有 `drop` 能力的值) + x +} +``` + +If a final expression is not present in a block---that is, if there is a trailing semicolon `;`, +there is an implicit unit `()` value. Similarly, if the expression block is empty, there is an +implicit unit `()` value. + +如果块中不存在最终表达式 —— 也就是说,如果有一个尾随分号 `;`,则含有一个隐式的[单值(unit)`()`](https://zh.wikipedia.org/wiki/%E5%8D%95%E5%80%BC%E7%B1%BB%E5%9E%8B)。同样,如果表达式块为空,那么也存在隐式的单值 `()`。 + +```move +// 两者是等价的 +{ x = x + 1; 1 / x; } +{ x = x + 1; 1 / x; () } +``` + +```move +// 两者是等价的 +{ } +{ () } +``` + +An expression block is itself an expression and can be used anyplace an expression is used. (Note: +The body of a function is also an expression block, but the function body cannot be replaced by +another expression.) + +表达式块本身就是一个表达式,可以在任何使用表达式的地方使用。(注意:函数体也是一个表达式块,但函数体不能被另一个表达式替换。) + +```move +let my_vector: vector> = { + let v = vector::empty(); + vector::push_back(&mut v, b"hello"); + vector::push_back(&mut v, b"goodbye"); + v +}; +``` + +(The type annotation is not needed in this example and only added for clarity.) + +(此示例中不需要类型标注,只是为了清楚起见而添加。) + +### 遮蔽(Shadowing) + +If a `let` introduces a local variable with a name already in scope, that previous variable can no +longer be accessed for the rest of this scope. This is called _shadowing_. + +如果一个 `let` 引入了一个名称已经在作用域中的局部变量,则该作用域的剩余部分将无法再访问先前的变量。这称为*遮蔽(shadowing)*。 + +```move +let x = 0; +assert!(x == 0, 42); + +let x = 1; // x 被遮蔽了 +assert!(x == 1, 42); +``` + +When a local is shadowed, it does not need to retain the same type as before. + +当局部变量被遮蔽时,它不需要保留与以前相同的类型。 + +```move +let x = 0; +assert!(x == 0, 42); + +let x = b"hello"; // x 被遮蔽了 +assert!(x == b"hello", 42); +``` + +After a local is shadowed, the value stored in the local still exists, but will no longer be +accessible. This is important to keep in mind with values of types without the +[`drop` ability](./abilities.md), as ownership of the value must be transferred by the end of the +function. + +在局部变量被遮蔽后,存储在局部变量的值仍然存在,但是将不再可访问。对于没有 [`drop` 能力](./abilities.md)的类型的值,请记住这一点很重要,因为值的所有权必须在函数结束时转移。 + +```move +address 0x42 { + module example { + struct Coin has store { value: u64 } + + fun unused_resource(): Coin { + let x = Coin { value: 0 }; // ERROR! +// ^ This local still contains a value without the `drop` ability(这个局部变量仍然包含一个没有 `drop` 能力的值) + x.value = 1; + let x = Coin { value: 10 }; + x +// ^ Invalid return(无效的返回) + } + } +} +``` + +When a local is shadowed inside a scope, the shadowing only remains for that scope. The shadowing is +gone once that scope ends. + +当局部变量在作用域内被遮蔽时,该遮蔽作用仅保留在该作用域内。一旦该作用域结束,遮蔽作用就消失了。 + +```move +let x = 0; +{ + let x = 1; + assert!(x == 1, 42); +}; +assert!(x == 0, 42); +``` + +Remember, locals can change type when they are shadowed. + +请记住,局部变量在被遮蔽时可以更改类型。 + +```move +let x = 0; +{ + let x = b"hello"; + assert!(x = b"hello", 42); +}; +assert!(x == 0, 42); +``` + +## 移动和复制(Move and Copy) + +All local variables in Move can be used in two ways, either by `move` or `copy`. If one or the other +is not specified, the Move compiler is able to infer whether a `copy` or a `move` should be used. +This means that in all of the examples above, a `move` or a `copy` would be inserted by the +compiler. A local variable cannot be used without the use of `move` or `copy`. + +`copy` will likely feel the most familiar coming from other programming languages, as it creates a +new copy of the value inside of the variable to use in that expression. With `copy`, the local +variable can be used more than once. + +Move 中的所有局部变量都可以通过两种方式使用,通过 `move` 或 `copy`。如果未指定其中之一,则 Move 编译器能够推断应该使用 `copy` 还是 `move`。这意味着在上述所有示例中,编译器将插入 `move` 或 `copy`。如果不使用 `move` 或 `copy`,就不能使用局部变量。 + +`copy` 对来自其他编程语言的开发者来说可能会觉得最熟悉,因为它会在变量内部创建一个新的副本值以在该表达式中使用。使用 `copy`,局部变量可以被多次使用。 + +```move +let x = 0; +let y = copy x + 1; +let z = copy x + 2; +``` + +Any value with the `copy` [ability](./abilities.md) can be copied in this way. + +`move` takes the value out of the local variable _without_ copying the data. After a `move` occurs, +the local variable is unavailable. + +任何具有 `copy` [能力](./abilities.md)的值都可以通过这种方式复制。 + +`move` 从局部变量中取出值*而不是*复制数据。`移动(move)`发生后,局部变量将不可用。 + +```move +let x = 1; +let y = move x + 1; +// ------ Local was moved here(局部变量被移动到这里了) +let z = move x + 2; // 错误! +// ^^^^^^ Invalid usage of local 'x'(局部变量“x”的无效使用方式) +y + z +``` + +### 安全性(Safety) + +Move's type system will prevent a value from being used after it is moved. This is the same safety +check described in [`let` declaration](#let-bindings) that prevents local variables from being used +before it is assigned a value. + +Move 的类型系统会阻止一个值在移动后被使用。这与 [`let` 声明](#let-绑定let-bindings)中描述的防止在局部变量被赋值之前使用的安全检查相同。 + + + + + +### 推断(Inference) + +As mentioned above, the Move compiler will infer a `copy` or `move` if one is not indicated. The +algorithm for doing so is quite simple: + +- Any scalar value with the `copy` [ability](./abilities.md) is given a `copy`. +- Any reference (both mutable `&mut` and immutable `&`) is given a `copy`. + - Except under special circumstances where it is made a `move` for predictable borrow checker errors. +- Any other value is given a `move`. + - This means that even though other values might be have the `copy` [ability](./abilities.md), it must be done _explicitly_ by the programmer. + - This is to prevent accidental copies of large data structures. + +如上所述,如果未指明,Move 编译器将推断出 `copy` 还是 `move`。这样做的算法非常简单: + +- 任何带有 `copy` [能力](./abilities.md)的标量值都被赋予了 `copy`。 +- 任何引用(可变的 `&mut` 和不可变的 `&`)都被赋予 `copy`。 + - 除非在可预测的借用检查器错误的特殊情况下,会进行 `move` 操作。 +- 任何其他值都被赋予 `move`。 + - 这意味着即使其他值可能具有 `copy` [能力](./abilities.md),它也必须由程序员*显式*声明。 + - 这是为了防止意外地复制很大的数据结构。 + +例如: + +```move +let s = b"hello"; +let foo = Foo { f: 0 }; +let coin = Coin { value: 0 }; + +let s2 = s; // 移动 +let foo2 = foo; // 移动 +let coin2 = coin; // 移动 + +let x = 0; +let b = false; +let addr = @0x42; +let x_ref = &x; +let coin_ref = &mut coin2; + +let x2 = x; // 复制 +let b2 = b; // 复制 +let addr2 = @0x42; // 复制 +let x_ref2 = x_ref; // 复制 +let coin_ref2 = coin_ref; // 复制 +``` diff --git a/vendors/move/crates/documentation/book/translations/move-book-zh/src/vector.md b/vendors/move/crates/documentation/book/translations/move-book-zh/src/vector.md new file mode 100644 index 000000000..286892a28 --- /dev/null +++ b/vendors/move/crates/documentation/book/translations/move-book-zh/src/vector.md @@ -0,0 +1,152 @@ +# 向量 + +`vector` 是 Move 提供的唯一原始集合类型。`vector` 是类型为 `T` 的同构集合,可以通过从"末端"推入/弹出(出栈/入栈,译者注)值来增长或缩小。 +*(与 Rust 一样,向量(vector)是一种可以存放任何类型的可变大小的容器,也可称为[动态数组](https://en.wikipedia.org/wiki/Dynamic_array),与 Python 中的[列表(list)](https://computersciencewiki.org/index.php/Lists)不同,译者注)* + +`vector` 可以用任何类型 `T` 实例化。例如,`vector`、`vector
`、`vector<0x42::MyModuel::MyResource>` 和 `vector>` 都是有效的向量类型。 + +## 字面量 + +### 通用 `vector` 字面量 + +任何类型的向量都可以通过 `vector` 字面量创建。 + +| 语法 | 类型 | 描述 | +|-----------------------|-------------------------------------------------------------------------------|-----------------------------------| +| `vector[]` | `vector[]: vector` 其中 `T` 是任何单一的非引用类型 | 一个空向量 | +| `vector[e1, ..., en]` | `vector[e1, ..., en]: vector` where `e_i: T` 满足 `0 < i <= n` and `n > 0` | 带有 `n` 个元素(长度为 n)的向量 | + +在这些情况下,`vector` 的类型是从元素类型或从向量的使用上推断出来的。如果无法推断类型或者只是为了更清楚地表示,则可以显式指定类型: + +```move +vector[]: vector +vector[e1, ..., en]: vector +``` + +#### 向量字面量示例 + +```move +(vector[]: vector); +(vector[0u8, 1u8, 2u8]: vector); +(vector[]: vector); +(vector
[@0x42, @0x100]: vector
); +``` + +### `vector` 字面量 + +Move 中向量的一个常见用例是表示“字节数组”,用 `vector` 表示。这些值通常用于加密目的,例如公钥或哈希结果。这些值非常常见,以至于提供了特定的语法以使值更具可读性,而不是必须使用 `vector[]`,其中每个单独的 `u8` 值都以数字形式指定。 + +目前支持两种类型的 `vector` 字面量,*字节字符串*和*十六进制字符串*。 + +#### 字节字符串 + +字节字符串是带引号的字符串字面量,以 `b` 为前缀,例如,`b"Hello!\n"`。 + +这些是允许转义序列的 ASCII 编码字符串。目前,支持的转义序列如下: + +| 转义序列 | 描述 | +|----------|---------------------------------------------| +| `\n` | 换行 | +| `\r` | 回车 | +| `\t` | 制表符 | +| `\\` | 反斜杠 | +| `\0` | Null | +| `\"` | 引号 | +| `\xHH` | 十六进制进制转义,插入十六进制字节序列 `HH` | + +#### 十六进制字符串 + +十六进制字符串是以 `x` 为前缀的带引号的字符串字面量,例如,`x"48656C6C6F210A"`。 + +每个字节对,范围从 `00` 到 `FF` 都被解析为十六进制编码的 `u8` 值。所以每个字节对对应于结果 `vector` 的单个条目。 + +#### 字符串字面量示例 + +```move +script { + fun byte_and_hex_strings() { + assert!(b"" == x"", 0); + assert!(b"Hello!\n" == x"48656C6C6F210A", 1); + assert!(b"\x48\x65\x6C\x6C\x6F\x21\x0A" == x"48656C6C6F210A", 2); + assert!( + b"\"Hello\tworld!\"\n \r \\Null=\0" == + x"2248656C6C6F09776F726C6421220A200D205C4E756C6C3D00", + 3 + ); + } +} +``` + +## 操作 + +`vector` 通过 Move 标准库里的 `std::vector` 模块支持以下操作: + +| 函数 | 描述 | 中止条件 | +|------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|----------------------| +| `vector::empty(): vector` | 创建一个可以存储 `T` 类型值的空向量 | 永不中止 | +| `vector::singleton(t: T): vector` | 创建一个包含 `t` 的大小为 1 的向量 | 永不中止 | +| `vector::push_back(v: &mut vector, t: T)` | 将 `t` 添加到 `v` 的尾部 | 永不中止 | +| `vector::pop_back(v: &mut vector): T` | 移除并返回 `v` 中的最后一个元素 | 如果 `v` 是空向量 | +| `vector::borrow(v: &vector, i: u64): &T` | 返回在索引 `i` 处对 `T` 的不可变引用 | 如果 `i` 越界 | +| `vector::borrow_mut(v: &mut vector, i: u64): &mut T` | 返回在索引 `i` 处对 `T` 的可变引用 | 如果 `i` 越界 | +| `vector::destroy_empty(v: vector)` | 销毁 `v` 向量 | 如果 `v` 不是空向量 | +| `vector::append(v1: &mut vector, v2: vector)` | 将 `v2` 中的元素添加到 `v1` 的末尾 | 永不中止 | +| `vector::contains(v: &vector, e: &T): bool` | 如果 `e` 在向量 `v` 里返回 true,否则返回 false | 永不中止 | +| `vector::swap(v: &mut vector, i: u64, j: u64)` | 交换向量 `v` 中第 `i` 个和第 `j` 个索引处的元素 | 如果 `i` 或 `j` 越界 | +| `vector::reverse(v: &mut vector)` | 反转向量 `v` 中元素的顺序 | 永不中止 | +| `vector::index_of(v: &vector, e: &T): (bool, u64)` | 如果 `e` 在索引 `i` 处的向量中,则返回 `(true, i)`。否则返回`(false, 0)` | 永不中止 | +| `vector::remove(v: &mut vector, i: u64): T` | 移除向量 `v` 中的第 `i` 个元素,移动所有后续元素。这里的时间复杂度是 O(n),并且保留了向量中元素的顺序 | 如果 `i` 越界 | +| `vector::swap_remove(v: &mut vector, i: u64): T` | 将向量中的第 `i` 个元素与最后一个元素交换,然后弹出该元素。这里的时间复杂度是 O(1),但是不保留向量中的元素顺序 | 如果 `i` 越界 | + +随着时间的推移可能会增加更多操作。 + +## 示例 + +```move +use std::vector; + +let v = vector::empty(); +vector::push_back(&mut v, 5); +vector::push_back(&mut v, 6); + +assert!(*vector::borrow(&v, 0) == 5, 42); +assert!(*vector::borrow(&v, 1) == 6, 42); +assert!(vector::pop_back(&mut v) == 6, 42); +assert!(vector::pop_back(&mut v) == 5, 42); +``` + +## 销毁和复制 `vector` + +`vector` 的某些行为取决于元素类型 `T` 的能力(ability),例如:如果向量中包含不具有 `drop` 能力的元素,那么不能像上面例子中的 `v` 一样隐式丢弃 —— 它们必须用 `vector::destroy_empty` 显式销毁。 + +请注意,除非向量 `vec` 包含零个元素,否则 `vector::destroy_empty` 将在运行时中止: + +```move +fun destroy_any_vector(vec: vector) { + vector::destroy_empty(vec) // 删除此行将导致编译器错误 +} +``` + +但是删除包含带有 `drop` 能力的元素的向量不会发生错误: + +```move +fun destroy_droppable_vector(vec: vector) { + // 有效! + // 不需要明确地做任何事情来销毁向量 +} +``` + +同样,除非元素类型具有 `copy` 能力,否则无法复制向量。换句话说,当且仅当 `T` 具有 `copy` 能力时,`vector` 才具有 `copy` 能力。然而,即使是可复制的向量也永远不会被隐式复制: + +```move +let x = vector::singleton(10); +let y = copy x; // 没有 copy 将导致编译器错误! +``` + +大向量的复制可能很昂贵,因此编译器需要显式 `copy` 以便更容易查看它们发生的位置。 + +有关更多详细信息,请参阅[类型能力](./abilities.md)和[泛型](./generics.md)部分。 + +## 所有权 + +[如上所述](#销毁和复制-vector),`vector` 值只有在元素值可以复制的时候才能复制。在这种情况下,复制必须通过显式 [`copy`](./variables.md#移动和复制) 或者[解引用 `*`](./references.md#通过引用读取和写入)。 diff --git a/vendors/move/crates/documentation/coding_guidelines.md b/vendors/move/crates/documentation/coding_guidelines.md new file mode 100644 index 000000000..9df7fbd49 --- /dev/null +++ b/vendors/move/crates/documentation/coding_guidelines.md @@ -0,0 +1,343 @@ +--- +id: coding-guidelines +title: Coding Guidelines +--- + +This document describes the coding guidelines for the Move Rust codebase. + +## Code formatting + +All code formatting is enforced with [rustfmt](https://github.com/rust-lang/rustfmt) with a project-specific configuration. Below is an example command to adhere to the Move project conventions. + +``` +$ cargo xfmt +``` + +## Code analysis + +[Clippy](https://github.com/rust-lang/rust-clippy) is used to catch common mistakes and is run as a part of continuous integration. Before submitting your code for review, you can run clippy with our configuration: + +``` +$ cargo xclippy --all-targets +``` + +In general, we follow the recommendations from [rust-lang-nursery](https://rust-lang.github.io/api-guidelines/) and [The Rust Programming Language](https://doc.rust-lang.org/book/). The remainder of this guide provides detailed guidelines on specific topics in order to achieve uniformity of the codebase. + +## Code documentation + +Any public fields, functions, and methods should be documented with [Rustdoc](https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments). + + Please follow the conventions as detailed below for modules, structs, enums, and functions. The *single line* is used as a preview when navigating Rustdoc. As an example, see the 'Structs' and 'Enums' sections in the [collections](https://doc.rust-lang.org/std/collections/index.html) Rustdoc. + + ``` + /// [Single line] One line summary description + /// + /// [Longer description] Multiple lines, inline code + /// examples, invariants, purpose, usage, etc. + [Attributes] If attributes exist, add after Rustdoc + ``` + +Example below: + +```rust +/// Represents (x, y) of a 2-dimensional grid +/// +/// A line is defined by 2 instances. +/// A plane is defined by 3 instances. +#[repr(C)] +struct Point { + x: i32, + y: i32, +} +``` + +### Terminology + +The Move codebase uses inclusive terminology (similar to other projects such as [the Linux kernel](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=49decddd39e5f6132ccd7d9fdc3d7c470b0061bb)). The terms below are recommended when appropriate. +* allowlist - a set of entities allowed access +* blocklist - a set of entities that are blocked from access +* primary/leader/main - a primary entity +* secondary/replica/follower - a secondary entity + +### Constants and fields + +Describe the purpose and definition of this data. If the unit is a measurement of time, include it, e.g., `TIMEOUT_MS` for timeout in milliseconds. + +### Functions and methods + +Document the following for each function: + +* The action the method performs - “This method *adds* a new transaction to the mempool.” Use *active voice* and *present tense* (i.e. adds/creates/checks/updates/deletes). +* Describe how and why to use this method. +* Any condition that must be met _before_ calling the method. +* State conditions under which the function will `panic!()` or returns an `Error` +* Brief description of return values. +* Any special behavior that is not obvious + +### README.md for top-level directories and other major components + +Each major component of Move needs to have a `README.md` file. + +This file should contain: + + * The *conceptual* *documentation* of the component. + * A link to the external API documentation for the component. + * A link to the main license of the project. + * A link to the main contributing guide for the project. + +A template for readmes: + +```markdown +# Component Name + +[Summary line: Start with one sentence about this component.] + +## Overview + +* Describe the purpose of this component and how the code in +this directory works. +* Describe the interaction of the code in this directory with +the other components. +* Describe the security model and assumptions about the crates +in this directory. Examples of how to describe the security +assumptions will be added in the future. + +## Implementation Details + +* Describe how the component is modeled. For example, why is the + code organized the way it is? +* Other relevant implementation details. + +## Binary, Argument, and Crate Naming + +Most tools that we use everyday (rustc, cargo, git, rg, etc.) use dashes `-` as +a separator for binary names and arguments and the [GNU software +manual](https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html) +dictates that long options should "consist of `--` followed by a name made of +alphanumeric characters and dashes". As such dashes `-` should be used as +separators in both binary names and command line arguments. + +In addition, it is generally accepted by many in the Rust community that dashes +`-` should be used as separators in crate names, i.e. `x25519-dalek`. + +## Code suggestions + +In the following sections, we have suggested some best practices for a uniform codebase. We will investigate and identify the practices that can be enforced using Clippy. This information will evolve and improve over time. + +### Attributes + +Make sure to use the appropriate attributes for handling dead code: + +``` +// For code that is intended for production usage in the future +#[allow(dead_code)] +// For code that is only intended for testing and +// has no intended production use +#[cfg(test)] +``` + +### Avoid Deref polymorphism + +Don't abuse the Deref trait to emulate inheritance between structs, and thus reuse methods. For more information, read [here](https://github.com/rust-unofficial/patterns/blob/master/anti_patterns/deref.md). + +### Comments + +We recommend that you use `//` and `///` comments rather than block comments `/* ... */` for uniformity and simpler grepping. + +### Concurrent types + +Concurrent types such as [`CHashMap`](https://docs.rs/crate/chashmap), [`AtomicUsize`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html), etc. have an immutable borrow on self i.e. `fn foo_mut(&self,...)` in order to support concurrent access on interior mutating methods. Good practices (such as those in the examples mentioned) avoid exposing synchronization primitives externally (e.g. `Mutex`, `RwLock`) and document the method semantics and invariants clearly. + +*When to use channels vs concurrent types?* + +Listed below are high-level suggestions based on experience: + +* Channels are for ownership transfer, decoupling of types, and coarse-grained messages. They fit well for transferring ownership of data, distributing units of work, and communicating async results. Furthermore, they help break circular dependencies (e.g. `struct Foo` contains an `Arc` and `struct Bar` contains an `Arc` that leads to complex initialization). + +* Concurrent types (e.g. such as [`CHashMap`](https://docs.rs/crate/chashmap) or structs that have interior mutability building on [`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html), [`RwLock`](https://doc.rust-lang.org/std/sync/struct.RwLock.html), etc.) are better suited for caches and states. + +### Error handling + +Error handling suggestions follow the [Rust book guidance](https://doc.rust-lang.org/book/ch09-00-error-handling.html). Rust groups errors into two major categories: recoverable and unrecoverable errors. Recoverable errors should be handled with [Result](https://doc.rust-lang.org/std/result/). Our suggestions on unrecoverable errors are listed below: + +*Panic* + +* `unwrap()` - Unwrap should only be used for test code. For all other use cases, prefer `expect()`. The only exception is if the error message is custom-generated, in which case use `.unwrap_or_else(|| panic!("error: {}", foo))`. +* `expect()` - Expect should be invoked when a system invariant is expected to be preserved. `expect()` is preferred over `unwrap()` and should contain a detailed error message on failure in most cases. +* `assert!()` - This macro is kept in both debug/release and should be used to protect invariants of the system as necessary. +* `unreachable!()` - This macro will panic on code that should not be reached (violating an invariant) and can be used where appropriate. + +In production (non-test) code, outside of lock management, all unrecoverable errors should be cleanly documented describing why said event is unrecoverable. For example, if the system is now in a bad state, state what that state is and the motivation for why a crash / restart is more effective than resolving it within a running system, and what if any steps an operator would need to take to resolve the issue. + +### Generics + +Generics allow dynamic behavior (similar to [`trait`](https://doc.rust-lang.org/book/ch10-02-traits.html) methods) with static dispatch. As the number of generic type parameters increases, the difficulty of using the type/method also increases (e.g. consider the combination of trait bounds required for this type, duplicate trait bounds on related types, etc.). In order to avoid this complexity, we generally try to avoid using a large number of generic type parameters. We have found that converting code with a large number of generic objects to trait objects with dynamic dispatch often simplifies our code. + +### Getters/setters + +In general, we follow naming recommendations for getters as specified [here](https://rust-lang.github.io/api-guidelines/naming.html#getter-names-follow-rust-convention-c-getter) and for setters as defined [here](https://github.com/rust-lang/rfcs/blob/master/text/0344-conventions-galore.md#gettersetter-apis). + +Getters/setters should be avoided for [`struct`](https://doc.rust-lang.org/book/ch05-00-structs.html) types in the C spirit: compound, passive data structures without internal invariants. Adding them only increases the complexity and number of lines of code without improving the developer experience. + +```rust +struct Foo { + size: usize, + key_to_value: HashMap +} + +impl Foo { + /// Simple getter follows xxx pattern + fn size(&self) -> usize { + self.size + } + + /// Setter follows set_xxx pattern + fn set_foo(&mut self, size: usize){ + self.size = size; + } + + /// Complex getter follows get_xxx pattern + fn get_value(&self, key: u32) -> Option<&u32> { + self.key_to_value.get(&key) + } +} +``` + +### Integer Arithmetic + +As every integer operation (`+`, `-`, `/`, `*`, etc.) implies edge-cases (e.g. overflows `u64::MAX + 1`, underflows `0u64 -1`, division by zero, etc.), +we use checked arithmetic instead of directly using math symbols. +It forces us to think of edge-cases, and handle them explicitely. +This is a brief and simplified mini guide of the different functions that exist to handle integer arithmetic: + +* [checked_](https://doc.rust-lang.org/std/primitive.u32.html#method.checked_add): use this function if you want to handle overflows and underflows as a special edge-case. It returns `None` if an underflow or overflow has happened, and `Some(operation_result)` otherwise. +* [overflowing_](https://doc.rust-lang.org/std/primitive.u32.html#method.overflowing_add): use this function if you want the result of an overflow to potentially wrap around (e.g. `u64::MAX.overflow_add(10) == (9, true)`). It returns the underflowed or overflowed result as well as a flag indicating if an overflow has occured or not. +* [wrapping_](https://doc.rust-lang.org/std/primitive.u32.html#method.wrapping_add): this is similar to overflowing operations, except that it returns the result directly. Use this function if you are sure that you want to handle underflows and overflows by wrapping around. +* [saturating_](https://doc.rust-lang.org/std/primitive.u32.html#method.saturating_add): if an overflow occurs, the result is kept within the boundary of the type (e.g. `u64::MAX.saturating_add(1) == u64::MAX`). + +### Logging + +We currently use [log](https://docs.rs/log/) for logging. + +* [error!](https://docs.rs/log/0.4.14/log/macro.error.html) - Error-level messages have the highest urgency in [log](https://docs.rs/log/). An unexpected error has occurred (e.g. exceeded the maximum number of retries to complete an RPC or inability to store data to local storage). +* [warn!](https://docs.rs/log/0.4.14/log/macro.warn.html) - Warn-level messages help notify admins about automatically handled issues (e.g. retrying a failed network connection or receiving the same message multiple times, etc.). +* [info!](https://docs.rs/log/0.4.14/log/macro.info.html) - Info-level messages are well suited for "one-time" events (such as logging state on one-time startup and shutdown) or periodic events that are not frequently occurring - e.g. changing the validator set every day. +* [debug!](https://docs.rs/log/0.4.14/log/macro.debug.html) - Debug-level messages can occur frequently (i.e. potentially > 1 message per second) and are not typically expected to be enabled in production. +* [trace!](https://docs.rs/log/0.4.14/log/macro.trace.html) - Trace-level logging is typically only used for function entry/exit. + +### Testing + +*Unit tests* + +We follow the general guidance provided [here](https://doc.rust-lang.org/book/ch11-03-test-organization.html). Ideally, all code should be unit tested. Unit tests should be in the same file as the code it is testing though in a distinct module, using the following syntax: + +```rust +struct Foo { +} + +impl Foo { + pub fn magic_number() -> u8 { + 42 + } +} + +#[cfg(test)] +mod tests { + #test + fn verify_magic_number() { + assert_eq!(Foo::magic_number(), 42); + } +} +``` + +*Property-based tests* + +Move contains [property-based tests](https://blog.jessitron.com/2013/04/25/property-based-testing-what-is-it/) written in Rust using the [`proptest` framework](https://github.com/AltSysrq/proptest). Property-based tests generate random test cases and assert that invariants, also called *properties*, hold for the code under test. + +Some examples of properties tested in Move: + +* Every serializer and deserializer pair is tested for correctness with random inputs to the serializer. Any pair of functions that are inverses of each other can be tested this way. +* The results of executing common transactions through the VM are tested using randomly generated scenarios and verified with an *Oracle*. + +A tutorial for `proptest` can be found in the [`proptest` book](https://altsysrq.github.io/proptest-book/proptest/getting-started.html). + +References: + +* [What is Property Based Testing?](https://hypothesis.works/articles/what-is-property-based-testing/) (includes a comparison with fuzzing) +* [An introduction to property-based testing](https://fsharpforfunandprofit.com/posts/property-based-testing/) +* [Choosing properties for property-based testing](https://fsharpforfunandprofit.com/posts/property-based-testing-2/) + +### Conditional compilation of tests + +Move [conditionally +compiles](https://doc.rust-lang.org/stable/reference/conditional-compilation.html) +code that is *only relevant for tests, but does not consist of tests* (unitary +or otherwise). Examples of this include proptest strategies, implementations +and derivations of specific traits (e.g. the occasional `Clone`), helper +functions, etc. Since Cargo is [currently not equipped for automatically activating features +in tests/benchmarks](https://github.com/rust-lang/cargo/issues/2911), we rely on two +conditions to perform this conditional compilation: +- the test flag, which is activated by dependent test code in the same crate + as the conditional test-only code. +- the `fuzzing` custom feature, which is used to enable fuzzing and testing +related code in downstream crates. Note that this must be passed explicitly to +`cargo xtest` and `cargo x bench`. Never use this in `[dependencies]` unless +the crate is only for testing. + +As a consequence, it is recommended that you set up your test-only code in the following fashion. + +**For production crates:** + +Production crates are defined as the set of crates that create externally published artifacts. + +For the sake of example, we'll consider you are defining a test-only helper function `foo` in `foo_crate`: + +1. Define the `fuzzing` flag in `foo_crate/Cargo.toml` and make it non-default: + ```toml + [features] + default = [] + fuzzing = [] + ``` +2. Annotate your test-only helper `foo` with both the `test` flag (for in-crate callers) and the `"fuzzing"` custom feature (for out-of-crate callers): + ```rust + #[cfg(any(test, feature = "fuzzing"))] + fn foo() { ... } + ``` +3. (optional) Use `cfg_attr` to make test-only trait derivations conditional: + ```rust + #[cfg_attr(any(test, feature = "testing"), derive(FooTrait))] + #[derive(Debug, Display, ...)] // inconditional derivations + struct Foo { ... } + ``` +4. (optional) Set up feature transitivity for crates that call crates that have test-only members. Let's say it's the case of `bar_crate`, which, through its test helpers, calls into `foo_crate` to use your test-only `foo`. Here's how you would set up `bar_crate/Cargo.toml`: + ```toml + [features] + default = [] + fuzzing = ["foo_crate/fuzzing"] + ``` + +**For test-only crates:** + +Test-only crates do not create published artifacts. They consist of tests, benchmarks or other code that verifies +the correctness or performance of published artifacts. Test-only crates are +explicitly listed in `x.toml` under `[workspace.test-only]`. + +These crates do not need to use the above setup. Instead, they can enable the `fuzzing` feature in production crates +directly. + +```toml +[dependencies] +foo_crate = { path = "...", features = ["fuzzing"] } +``` + +*A final note on integration tests*: All tests that use conditional test-only +elements in another crate need to activate the "fuzzing" feature through the +`[features]` section in their `Cargo.toml`. [Integration +tests](https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html) +can neither rely on the `test` flag nor do they have a proper `Cargo.toml` for +feature activation. In the Move codebase, we therefore recommend that +*integration tests which depend on test-only code in their tested crate* be +extracted to their own test-only crate. See `language/move-binary-format/serializer_tests` +for an example of such an extracted integration test. + +*Note for developers*: The reason we use a feature re-export (in the `[features]` section of the `Cargo.toml` is that a profile is not enough to activate the `"fuzzing"` feature flag. See [cargo-issue #291](https://github.com/rust-lang/cargo/issues/2911) for details). diff --git a/vendors/move/crates/documentation/examples/diem-framework/build_all.sh b/vendors/move/crates/documentation/examples/diem-framework/build_all.sh new file mode 100644 index 000000000..cb5a07535 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/build_all.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (c) The Diem Core Contributors +# Copyright (c) The Move Contributors +# SPDX-License-Identifier: Apache-2.0 + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +cd "${SCRIPT_DIR}/move-packages/DPN" && cargo run -p df-cli -- build && +cd "${SCRIPT_DIR}/move-packages/core" && cargo run -p df-cli -- build && +cd "${SCRIPT_DIR}/move-packages/experimental" && cargo run -p df-cli -- build diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/cli/Cargo.toml b/vendors/move/crates/documentation/examples/diem-framework/crates/cli/Cargo.toml new file mode 100644 index 000000000..0a335595a --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/cli/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "df-cli" +version = "0.1.0" +description = "CLI frontend for the Move compiler and VM (with Diem Framework)" +authors = ["Diem Association "] +license = "Apache-2.0" +publish = false +edition = "2021" + +[dependencies] +anyhow = "1.0.52" +clap = { version = "3.1.8", features = ["derive"] } + +bcs = "0.1.4" +move-cli = { path = "../../../../../move-cli" } +move-core-types = { path = "../../../../../move-core-types" } + +move-stdlib = { path = "../../../../../move-stdlib" } +move-vm-test-utils = { path = "../../../../../move-vm/test-utils" } +move-vm-types = { path = "../../../../../move-vm/types" } + +diem-framework-natives = { path = "../natives" } + +[dev-dependencies] +datatest-stable = "0.1.1" diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/cli/src/main.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/cli/src/main.rs new file mode 100644 index 000000000..ec83cef14 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/cli/src/main.rs @@ -0,0 +1,65 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use clap::Parser; +use move_cli::{Command, Move}; +use move_core_types::{errmap::ErrorMapping, language_storage::CORE_CODE_ADDRESS}; +use move_vm_test_utils::gas_schedule::{ + new_from_instructions, zero_cost_instruction_table, CostTable, +}; + +#[derive(Parser)] +pub struct DfCli { + #[clap(flatten)] + move_args: Move, + + #[clap(subcommand)] + cmd: DfCommands, +} + +#[derive(Parser)] +pub enum DfCommands { + #[clap(flatten)] + Command(Command), + // extra commands available only in df-cli can be added below +} + +fn cost_table() -> CostTable { + let instruction_table = zero_cost_instruction_table(); + new_from_instructions(instruction_table) +} + +fn main() -> Result<()> { + // let error_descriptions: ErrorMapping = + // bcs::from_bytes(diem_framework_releases::current_error_descriptions())?; + + let natives = move_stdlib::natives::all_natives( + CORE_CODE_ADDRESS, + // We may want to switch to a different gas schedule in the future, but for now, + // the all-zero one should be enough. + move_stdlib::natives::GasParameters::zeros(), + ) + .into_iter() + .chain(move_stdlib::natives::nursery_natives( + CORE_CODE_ADDRESS, + // We may want to switch to a different gas schedule in the future, but for now, + // the all-zero one should be enough. + move_stdlib::natives::NurseryGasParameters::zeros(), + )) + .chain(diem_framework_natives::all_natives(CORE_CODE_ADDRESS)) + .collect::>(); + + let args = DfCli::parse(); + match args.cmd { + DfCommands::Command(cmd) => move_cli::run_cli( + natives, + &cost_table(), + // TODO: implement this + &ErrorMapping::default(), + args.move_args, + cmd, + ), + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/Cargo.toml b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/Cargo.toml new file mode 100644 index 000000000..f9a6e08ba --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "diem-crypto-derive" +version = "0.0.3" +authors = ["Diem Association "] +publish = false +edition = "2021" +license = "Apache-2.0" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.24" +quote = "1.0.9" +syn = { version = "1.0.64", features = ["derive"] } + +[dev-dependencies] +anyhow = "1.0.52" diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/hasher.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/hasher.rs new file mode 100644 index 000000000..af9c1eb01 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/hasher.rs @@ -0,0 +1,21 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +/// Converts a camel-case string to snake-case +pub fn camel_to_snake(text: &str) -> String { + let mut out = String::with_capacity(text.len()); + let mut first = true; + text.chars().for_each(|c| { + if !first && c.is_uppercase() { + out.push('_'); + out.extend(c.to_lowercase()); + } else if first { + first = false; + out.extend(c.to_lowercase()); + } else { + out.push(c); + } + }); + out +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/lib.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/lib.rs new file mode 100644 index 000000000..d0ec0f769 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/lib.rs @@ -0,0 +1,447 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +//! # Derive macros for crypto operations +//! This crate contains four types of derive macros: +//! +//! - the `SilentDebug` and SilentDisplay macros are meant to be used on private key types, and +//! elide their input for confidentiality. +//! - the `Deref` macro helps derive the canonical instances on new types. +//! - the derive macros for `diem_crypto::traits`, namely `ValidCryptoMaterial`, `PublicKey`, `PrivateKey`, +//! `VerifyingKey`, `SigningKey` and `Signature` are meant to be derived on simple unions of types +//! implementing these traits. +//! - the derive macro for `diem_crypto::hash::CryptoHasher`, which defines +//! the domain-separation hasher structures described in `diem_crypto::hash` +//! (look there for details). This derive macro has for sole difference that it +//! automatically picks a unique salt for you, using the Serde name. For a container `Foo`, +//! this is usually equivalent to: +//! ```ignore +//! define_hasher! { +//! ( +//! FooHasher, +//! FOO_HASHER, +//! b"Foo" +//! ) +//! } +//! ``` +//! +//! # Unions of Signing Traits, in detail +//! +//! Those types typically come into play when you need to accept several +//! alternatives at runtime for several signature and verification schemes +//! (ex: BLS or EdDSA, see below). In this case, it is possible to declare +//! a triplet of enum types that each describe a 'sum type' (coproduct) of these +//! alternatives. This happens to be a signing scheme itself (it has +//! canonical signature, signing & verifying key types, and verifies all +//! expected properties by trivial dispatch). +//! +//! The macros below let you define this type of union trivially under two conditions: +//! - that the variant tags for the enum have the same name, i.e. if the BLS variant for the +//! `SignatureUnion` is `SignatureUnion::BLS(BLS12381Signature)`, then the variant of the +//! `PublicKeyUnion` for BLS must also be `PublicKeyUnion::BLS`, +//! - that you specify the associated types `PrivateKeyType`, `SignatureType` and `PublicKeyType` +//! for each of the three unions. `PrivateKeyType` provides the value for the +//! `VerifyingKeyMaterial` and `PublicKeyMaterial` associated types, `PublicKeyType` provides the +//! valid for the `SigningKeyMaterial` and `PrivateKeyMaterial` associated types and +//! `SignatureType` provides the value for the `SignatureMaterial` associated type. +//! +//! ## Example +//! +//! ```ignore +//! # #[macro_use] extern crate crypto-derive; +//! use diem_crypto::{ +//! hash::HashValue, +//! bls12381::{BLS12381PrivateKey, BLS12381PublicKey, BLS12381Signature}, +//! ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature}, +//! }; +//! use diem_crypto_derive::{ +//! SilentDebug, PrivateKey, PublicKey, Signature, SigningKey, ValidCryptoMaterial, VerifyingKey, +//! }; +//! +//! /// Generic public key enum +//! #[derive( +//! Debug, Clone, PartialEq, Eq, Hash, ValidCryptoMaterial, PublicKey, VerifyingKey, +//! )] +//! #[PrivateKeyType = "GenericPrivateKey"] +//! #[SignatureType = "GenericSignature"] +//! pub enum GenericPublicKey { +//! /// Ed25519 public key +//! Ed(Ed25519PublicKey), +//! /// BLS12-381 public key +//! BLS(BLS12381PublicKey), +//! } +//! /// Generic private key enum +//! #[derive(SilentDebug, ValidCryptoMaterial, PrivateKey, SigningKey)] +//! #[PublicKeyType = "GenericPublicKey"] +//! #[SignatureType = "GenericSignature"] +//! pub enum GenericPrivateKey { +//! /// Ed25519 private key +//! Ed(Ed25519PrivateKey), +//! /// BLS12-381 private key +//! BLS(BLS12381PrivateKey), +//! } +//! /// Generic signature enum +//! #[allow(clippy::large_enum_variant)] +//! #[derive(Clone, Debug, PartialEq, Eq, Hash, Signature)] +//! #[PrivateKeyType = "GenericPrivateKey"] +//! #[PublicKeyType = "GenericPublicKey"] +//! pub enum GenericSignature { +//! /// Ed25519 signature +//! Ed(Ed25519Signature), +//! /// BLS12-381 signature +//! BLS(BLS12381Signature), +//! } +//! ``` + +#![forbid(unsafe_code)] + +extern crate proc_macro; + +mod hasher; +mod unions; + +use hasher::camel_to_snake; +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::quote; +use std::iter::FromIterator; +use syn::{parse_macro_input, parse_quote, Data, DeriveInput, Ident}; +use unions::*; + +#[proc_macro_derive(SilentDisplay)] +pub fn silent_display(source: TokenStream) -> TokenStream { + let ast: DeriveInput = syn::parse(source).expect("Incorrect macro input"); + let name = &ast.ident; + let gen = quote! { + // In order to ensure that secrets are never leaked, Display is elided + impl ::std::fmt::Display for #name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "", stringify!(#name)) + } + } + }; + gen.into() +} + +#[proc_macro_derive(SilentDebug)] +pub fn silent_debug(source: TokenStream) -> TokenStream { + let ast: DeriveInput = syn::parse(source).expect("Incorrect macro input"); + let name = &ast.ident; + let gen = quote! { + // In order to ensure that secrets are never leaked, Debug is elided + impl ::std::fmt::Debug for #name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "", stringify!(#name)) + } + } + }; + gen.into() +} + +/// Deserialize from a human readable format where applicable +#[proc_macro_derive(DeserializeKey)] +pub fn deserialize_key(source: TokenStream) -> TokenStream { + let ast: DeriveInput = syn::parse(source).expect("Incorrect macro input"); + let name = &ast.ident; + let name_string = name.to_string(); + let gen = quote! { + impl<'de> ::serde::Deserialize<'de> for #name { + fn deserialize(deserializer: D) -> std::result::Result + where + D: ::serde::Deserializer<'de>, + { + if deserializer.is_human_readable() { + let encoded_key = ::deserialize(deserializer)?; + ValidCryptoMaterialStringExt::from_encoded_string(encoded_key.as_str()) + .map_err(::custom) + } else { + // In order to preserve the Serde data model and help analysis tools, + // make sure to wrap our value in a container with the same name + // as the original type. + #[derive(::serde::Deserialize)] + #[serde(rename = #name_string)] + struct Value<'a>(&'a [u8]); + + let value = Value::deserialize(deserializer)?; + #name::try_from(value.0).map_err(|s| { + ::custom(format!("{} with {}", s, #name_string)) + }) + } + } + } + }; + gen.into() +} + +/// Serialize into a human readable format where applicable +#[proc_macro_derive(SerializeKey)] +pub fn serialize_key(source: TokenStream) -> TokenStream { + let ast: DeriveInput = syn::parse(source).expect("Incorrect macro input"); + let name = &ast.ident; + let name_string = name.to_string(); + let gen = quote! { + impl ::serde::Serialize for #name { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: ::serde::Serializer, + { + if serializer.is_human_readable() { + self.to_encoded_string() + .map_err(::custom) + .and_then(|str| serializer.serialize_str(&str[..])) + } else { + // See comment in deserialize_key. + serializer.serialize_newtype_struct( + #name_string, + serde_bytes::Bytes::new(&ValidCryptoMaterial::to_bytes(self).as_slice()), + ) + } + } + } + }; + gen.into() +} + +#[proc_macro_derive(Deref)] +pub fn derive_deref(input: TokenStream) -> TokenStream { + let item = syn::parse(input).expect("Incorrect macro input"); + let (field_ty, field_access) = parse_newtype_fields(&item); + + let name = &item.ident; + let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl(); + + quote!( + impl #impl_generics ::std::ops::Deref for #name #ty_generics + #where_clause + { + type Target = #field_ty; + + fn deref(&self) -> &Self::Target { + #field_access + } + } + ) + .into() +} + +#[proc_macro_derive(ValidCryptoMaterial)] +pub fn derive_enum_valid_crypto_material(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + + let name = &ast.ident; + match ast.data { + Data::Enum(ref variants) => impl_enum_valid_crypto_material(name, variants), + Data::Struct(_) | Data::Union(_) => { + panic!("#[derive(ValidCryptoMaterial)] is only defined for enums") + }, + } +} + +#[proc_macro_derive(PublicKey, attributes(PrivateKeyType))] +pub fn derive_enum_publickey(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + + let name = &ast.ident; + let private_key_type = get_type_from_attrs(&ast.attrs, "PrivateKeyType").unwrap(); + match ast.data { + Data::Enum(ref variants) => impl_enum_publickey(name, private_key_type, variants), + Data::Struct(_) | Data::Union(_) => { + panic!("#[derive(PublicKey)] is only defined for enums") + }, + } +} + +#[proc_macro_derive(PrivateKey, attributes(PublicKeyType))] +pub fn derive_enum_privatekey(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + + let name = &ast.ident; + let public_key_type = get_type_from_attrs(&ast.attrs, "PublicKeyType").unwrap(); + match ast.data { + Data::Enum(ref variants) => impl_enum_privatekey(name, public_key_type, variants), + Data::Struct(_) | Data::Union(_) => { + panic!("#[derive(PrivateKey)] is only defined for enums") + }, + } +} + +#[proc_macro_derive(VerifyingKey, attributes(PrivateKeyType, SignatureType))] +pub fn derive_enum_verifyingkey(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + + let name = &ast.ident; + let private_key_type = get_type_from_attrs(&ast.attrs, "PrivateKeyType").unwrap(); + let signature_type = get_type_from_attrs(&ast.attrs, "SignatureType").unwrap(); + match ast.data { + Data::Enum(ref variants) => { + impl_enum_verifyingkey(name, private_key_type, signature_type, variants) + }, + Data::Struct(_) | Data::Union(_) => { + panic!("#[derive(PrivateKey)] is only defined for enums") + }, + } +} + +#[proc_macro_derive(SigningKey, attributes(PublicKeyType, SignatureType))] +pub fn derive_enum_signingkey(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + + let name = &ast.ident; + let public_key_type = get_type_from_attrs(&ast.attrs, "PublicKeyType").unwrap(); + let signature_type = get_type_from_attrs(&ast.attrs, "SignatureType").unwrap(); + match ast.data { + Data::Enum(ref variants) => { + impl_enum_signingkey(name, public_key_type, signature_type, variants) + }, + Data::Struct(_) | Data::Union(_) => { + panic!("#[derive(PrivateKey)] is only defined for enums") + }, + } +} + +#[proc_macro_derive(Signature, attributes(PublicKeyType, PrivateKeyType))] +pub fn derive_enum_signature(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + + let name = &ast.ident; + let public_key_type = get_type_from_attrs(&ast.attrs, "PublicKeyType").unwrap(); + let private_key_type = get_type_from_attrs(&ast.attrs, "PrivateKeyType").unwrap(); + match ast.data { + Data::Enum(ref variants) => { + impl_enum_signature(name, public_key_type, private_key_type, variants) + }, + Data::Struct(_) | Data::Union(_) => { + panic!("#[derive(PrivateKey)] is only defined for enums") + }, + } +} + +// There is a unit test for this logic in the crypto crate, at +// diem_crypto::unit_tests::cryptohasher — you may have to modify it if you +// edit the below. +#[proc_macro_derive(CryptoHasher)] +pub fn hasher_dispatch(input: TokenStream) -> TokenStream { + let item = parse_macro_input!(input as DeriveInput); + let hasher_name = Ident::new( + &format!("{}Hasher", &item.ident.to_string()), + Span::call_site(), + ); + let snake_name = camel_to_snake(&item.ident.to_string()); + let static_seed_name = Ident::new( + &format!("{}_SEED", snake_name.to_uppercase()), + Span::call_site(), + ); + + let static_hasher_name = Ident::new( + &format!("{}_HASHER", snake_name.to_uppercase()), + Span::call_site(), + ); + let type_name = &item.ident; + let param = if item.generics.params.is_empty() { + quote!() + } else { + let args = proc_macro2::TokenStream::from_iter( + std::iter::repeat(quote!(())).take(item.generics.params.len()), + ); + quote!(<#args>) + }; + + let out = quote!( + /// Cryptographic hasher for an BCS-serializable #item + #[derive(Clone)] + pub struct #hasher_name(diem_crypto::hash::DefaultHasher); + + static #static_seed_name: diem_crypto::_once_cell::sync::OnceCell<[u8; 32]> = diem_crypto::_once_cell::sync::OnceCell::new(); + + impl #hasher_name { + fn new() -> Self { + let name = diem_crypto::_serde_name::trace_name::<#type_name #param>() + .expect("The `CryptoHasher` macro only applies to structs and enums"); + #hasher_name( + diem_crypto::hash::DefaultHasher::new(&name.as_bytes())) + } + } + + static #static_hasher_name: diem_crypto::_once_cell::sync::Lazy<#hasher_name> = + diem_crypto::_once_cell::sync::Lazy::new(|| #hasher_name::new()); + + + impl std::default::Default for #hasher_name + { + fn default() -> Self { + #static_hasher_name.clone() + } + } + + impl diem_crypto::hash::CryptoHasher for #hasher_name { + fn seed() -> &'static [u8; 32] { + #static_seed_name.get_or_init(|| { + let name = diem_crypto::_serde_name::trace_name::<#type_name #param>() + .expect("The `CryptoHasher` macro only applies to structs and enums.").as_bytes(); + diem_crypto::hash::DefaultHasher::prefixed_hash(&name) + }) + } + + fn update(&mut self, bytes: &[u8]) { + self.0.update(bytes); + } + + fn finish(self) -> diem_crypto::hash::HashValue { + self.0.finish() + } + } + + impl std::io::Write for #hasher_name { + fn write(&mut self, bytes: &[u8]) -> std::io::Result { + use diem_crypto::hash::CryptoHasher; + + self.0.update(bytes); + Ok(bytes.len()) + } + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + } + + ); + out.into() +} + +#[proc_macro_derive(BCSCryptoHash)] +pub fn bcs_crypto_hash_dispatch(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + let name = &ast.ident; + let hasher_name = Ident::new(&format!("{}Hasher", &name.to_string()), Span::call_site()); + let error_msg = syn::LitStr::new( + &format!("BCS serialization of {} should not fail", name), + Span::call_site(), + ); + let generics = add_trait_bounds(ast.generics); + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let out = quote!( + impl #impl_generics diem_crypto::hash::CryptoHash for #name #ty_generics #where_clause { + type Hasher = #hasher_name; + + fn hash(&self) -> diem_crypto::hash::HashValue { + use diem_crypto::hash::CryptoHasher; + + let mut state = Self::Hasher::default(); + bcs::serialize_into(&mut state, &self).expect(#error_msg); + state.finish() + } + } + ); + out.into() +} + +fn add_trait_bounds(mut generics: syn::Generics) -> syn::Generics { + for param in generics.params.iter_mut() { + if let syn::GenericParam::Type(type_param) = param { + type_param.bounds.push(parse_quote!(Serialize)); + } + } + generics +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/unions.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/unions.rs new file mode 100644 index 000000000..fbd813abf --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto-derive/src/unions.rs @@ -0,0 +1,309 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use proc_macro::TokenStream; +use quote::quote; +use syn::{DataEnum, Ident}; + +pub fn parse_newtype_fields(item: &syn::DeriveInput) -> (syn::Type, proc_macro2::TokenStream) { + let fields = match item.data { + syn::Data::Struct(ref body) => body.fields.iter().collect::>(), + _ => vec![], + }; + + let field_ty = match fields.len() { + 1 => Some(fields[0].ty.clone()), + _ => None, + }; + let field_ty = field_ty.expect("#[derive(Deref)] can only be used on structs with one field."); + + let field_name = match fields[0].ident { + Some(ref ident) => quote!(#ident), + None => quote!(0), + }; + + match field_ty { + syn::Type::Reference(syn::TypeReference { elem, .. }) => (*elem, quote!(self.#field_name)), + x => (x, quote!(&self.#field_name)), + } +} + +pub fn impl_enum_tryfrom(name: &Ident, variants: &DataEnum) -> proc_macro2::TokenStream { + // the TryFrom dispatch + let mut try_iter = variants.variants.iter(); + let first_variant = try_iter + .next() + .expect("#[derive(ValidCryptoMaterial] requires a non-empty enum."); + let first_variant_ident = &first_variant.ident; + let first_variant_arg = &first_variant + .fields + .iter() + .next() + .expect("Unrecognized enum for key types") + .ty; + + let mut try_chain = quote! { + #first_variant_arg::try_from(bytes).and_then(|key| Ok(#name::#first_variant_ident(key))) + }; + for variant in try_iter { + let variant_ident = &variant.ident; + let variant_arg = &variant + .fields + .iter() + .next() + .expect("Unrecognized enum for key types") + .ty; + try_chain.extend(quote!{ + .or_else(|_err| #variant_arg::try_from(bytes).and_then(|key| Ok(#name::#variant_ident(key)))) + }) + } + + quote! { + impl core::convert::TryFrom<&[u8]> for #name { + type Error = diem_crypto::CryptoMaterialError; + fn try_from(bytes: &[u8]) -> std::result::Result<#name, Self::Error> { + #try_chain + } + } + } +} + +fn match_enum_to_bytes(name: &Ident, variants: &DataEnum) -> proc_macro2::TokenStream { + // the ValidCryptoMaterial dispatch proper + let mut match_arms = quote! {}; + for variant in variants.variants.iter() { + let variant_ident = &variant.ident; + + match_arms.extend(quote! { + #name::#variant_ident(key) => key.to_bytes().to_vec(), + }); + } + match_arms +} + +pub fn impl_enum_valid_crypto_material(name: &Ident, variants: &DataEnum) -> TokenStream { + let mut try_from = impl_enum_tryfrom(name, variants); + + let to_bytes_arms = match_enum_to_bytes(name, variants); + + try_from.extend(quote! { + + impl diem_crypto::ValidCryptoMaterial for #name { + fn to_bytes(&self) -> Vec { + match self { + #to_bytes_arms + } + } + } + }); + try_from.into() +} + +pub fn get_type_from_attrs(attrs: &[syn::Attribute], attr_name: &str) -> syn::Result { + attrs + .iter() + .find(|attr| attr.path.is_ident(attr_name)) + .map_or_else( + || { + Err(syn::Error::new( + proc_macro2::Span::call_site(), + format!("Could not find attribute {}", attr_name), + )) + }, + |attr| match attr.parse_meta()? { + syn::Meta::NameValue(meta) => { + if let syn::Lit::Str(lit) = &meta.lit { + Ok(lit.clone()) + } else { + Err(syn::Error::new_spanned( + meta, + &format!("Could not parse {} attribute", attr_name)[..], + )) + } + }, + bad => Err(syn::Error::new_spanned( + bad, + &format!("Could not parse {} attribute", attr_name)[..], + )), + }, + ) +} + +pub fn impl_enum_publickey( + name: &Ident, + private_key_type: syn::LitStr, + variants: &DataEnum, +) -> TokenStream { + let pkt: syn::Type = private_key_type.parse().unwrap(); + let mut from_match_arms = quote! {}; + for variant in variants.variants.iter() { + let variant_ident = &variant.ident; + + from_match_arms.extend(quote! { + #pkt::#variant_ident(key) => #name::#variant_ident(key.into()), + }); + } + let mut res = quote! { + impl From<&#pkt> for #name { + fn from(public_key: &#pkt) -> Self { + match public_key { + #from_match_arms + } + } + } + }; + res.extend(quote! { + impl diem_crypto::PublicKey for #name { + type PrivateKeyMaterial = #pkt; + } + }); + res.into() +} + +pub fn impl_enum_privatekey( + name: &Ident, + public_key_type: syn::LitStr, + _variants: &DataEnum, +) -> TokenStream { + let pkt: syn::Type = public_key_type.parse().unwrap(); + let res = quote! { + impl diem_crypto::PrivateKey for #name { + type PublicKeyMaterial = #pkt; + } + }; + res.into() +} + +pub fn impl_enum_verifyingkey( + name: &Ident, + private_key_type: syn::LitStr, + signature_type: syn::LitStr, + _variants: &DataEnum, +) -> TokenStream { + let pkt: syn::Type = private_key_type.parse().unwrap(); + let st: syn::Type = signature_type.parse().unwrap(); + let res = quote! { + impl diem_crypto::VerifyingKey for #name { + type SigningKeyMaterial = #pkt; + type SignatureMaterial = #st; + } + impl diem_crypto::private::Sealed for #name {} + }; + res.into() +} + +pub fn impl_enum_signingkey( + name: &Ident, + public_key_type: syn::LitStr, + signature_type: syn::LitStr, + variants: &DataEnum, +) -> TokenStream { + let pkt: syn::Type = public_key_type.parse().unwrap(); + let st: syn::Type = signature_type.parse().unwrap(); + + let mut match_arms_arbitrary = quote! {}; + let mut match_struct_arms = quote! {}; + for variant in variants.variants.iter() { + let variant_ident = &variant.ident; + + match_struct_arms.extend(quote! { + #name::#variant_ident(key) => Self::SignatureMaterial::#variant_ident(key.sign(message)), + }); + match_arms_arbitrary.extend(quote! { + #name::#variant_ident(key) => Self::SignatureMaterial::#variant_ident(key.sign_arbitrary_message(message)), + }); + } + let res = quote! { + impl diem_crypto::SigningKey for #name { + type VerifyingKeyMaterial = #pkt; + type SignatureMaterial = #st; + + fn sign(&self, message: &T) -> Self::SignatureMaterial { + match self { + #match_struct_arms + } + } + + #[cfg(test)] + fn sign_arbitrary_message(&self, message: &[u8]) -> Self::SignatureMaterial { + match self { + #match_arms_arbitrary + } + } + } + impl diem_crypto::private::Sealed for #name {} + }; + res.into() +} + +pub fn impl_enum_signature( + name: &Ident, + public_key_type: syn::LitStr, + private_key_type: syn::LitStr, + variants: &DataEnum, +) -> TokenStream { + let priv_kt: syn::Type = private_key_type.parse().unwrap(); + let pub_kt: syn::Type = public_key_type.parse().unwrap(); + let mut res = impl_enum_tryfrom(name, variants); + let to_bytes_arms = match_enum_to_bytes(name, variants); + + let mut match_arms = quote! {}; + for variant in variants.variants.iter() { + let variant_ident = &variant.ident; + + match_arms.extend(quote! { + (#name::#variant_ident(sig), #pub_kt::#variant_ident(pk)) => { + sig.verify_arbitrary_msg(message, pk) + } + }) + } + + let mut match_struct_arms = quote! {}; + for variant in variants.variants.iter() { + let variant_ident = &variant.ident; + + match_struct_arms.extend(quote! { + (#name::#variant_ident(sig), #pub_kt::#variant_ident(pk)) => { + sig.verify(message, pk) + } + }) + } + + res.extend(quote! { + + impl diem_crypto::Signature for #name { + type VerifyingKeyMaterial = #pub_kt; + type SigningKeyMaterial = #priv_kt; + + fn verify(&self, message: &T, public_key: &Self::VerifyingKeyMaterial) -> std::result::Result<(), diem_crypto::error::Error> { + match (self, public_key) { + #match_struct_arms + _ => diem_crypto::error::bail!( + "provided the wrong alternative in {:?}!", + (self, public_key) + ), + } + } + + fn verify_arbitrary_msg(&self, message: &[u8], public_key: &Self::VerifyingKeyMaterial) -> std::result::Result<(), diem_crypto::error::Error> { + match (self, public_key) { + #match_arms + _ => diem_crypto::error::bail!( + "provided the wrong alternative in {:?}!", + (self, public_key) + ), + } + } + + fn to_bytes(&self) -> Vec { + match self { + #to_bytes_arms + } + } + } + + impl diem_crypto::private::Sealed for #name {} + }); + res.into() +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/Cargo.toml b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/Cargo.toml new file mode 100644 index 000000000..01036751e --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/Cargo.toml @@ -0,0 +1,63 @@ +[package] +name = "diem-crypto" +version = "0.0.3" +authors = ["Diem Association "] +publish = false +edition = "2021" +license = "Apache-2.0" + +[dependencies] +aes-gcm = "0.8.0" +anyhow = "1.0.52" +bytes = "1.0.1" +curve25519-dalek = { version = "0.1.0", package = "curve25519-dalek-fiat", default-features = false, features = ["std"] } +diem-crypto-derive = { path = "../crypto-derive" } +digest = "0.9.0" +ed25519-dalek = { version = "0.1.0", package = "ed25519-dalek-fiat", default-features = false, features = ["std", "serde"] } +hex = "0.4.3" +hkdf = "0.10.0" +mirai-annotations = "1.10.1" +once_cell = "1.7.2" +proptest = { version = "1.0.0", optional = true } +proptest-derive = { version = "0.3.0", optional = true } +rand = "0.8.0" +rand_core = { version = "0.6.2", default-features = false } +serde = { version = "1.0.124", features = ["derive"] } +serde-name = "0.1.1" +serde_bytes = "0.11.5" +sha2 = "0.9.3" +static_assertions = "1.1.0" +thiserror = "1.0.24" +tiny-keccak = { version = "2.0.2", features = ["sha3"] } +x25519-dalek = { version = "0.1.0", package = "x25519-dalek-fiat", default-features = false, features = ["std"] } + +bcs = "0.1.4" + +[dev-dependencies] +bitvec = "0.19.4" +byteorder = "1.4.3" +criterion = "0.3.4" +proptest = "1.0.0" +proptest-derive = "0.3.0" +ripemd160 = "0.9.1" +serde_json = "1.0.64" +sha3 = "0.9.1" +# TODO: some tests will fail if this is set to 1.0.63 +trybuild = "=1.0.53" + +[features] +default = ["fiat"] +assert-private-keys-not-cloneable = [] +cloneable-private-keys = [] +fuzzing = ["proptest", "proptest-derive", "cloneable-private-keys"] +fiat = ["curve25519-dalek/fiat_u64_backend", "ed25519-dalek/fiat_u64_backend", "x25519-dalek/fiat_u64_backend"] +u64 = ["curve25519-dalek/u64_backend", "ed25519-dalek/u64_backend", "x25519-dalek/u64_backend"] +u32 = ["curve25519-dalek/u32_backend", "ed25519-dalek/u32_backend", "x25519-dalek/u32_backend"] + +[[bench]] +name = "noise" +harness = false + +[[bench]] +name = "ed25519" +harness = false diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/README.md b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/README.md new file mode 100644 index 000000000..b27dcb6fd --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/README.md @@ -0,0 +1,29 @@ +The crypto component hosts all the implementations of cryptographic primitives we use in Diem: hashing, signing, and key derivation/generation. The parts of the library using traits.rs contains the crypto API enforcing type safety, verifiable random functions, EdDSA & MultiEdDSA signatures. + +## Overview + +Diem makes use of several cryptographic algorithms: + +* SHA-3 as the main hash function. It is standardized in [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf). It is based on the [tiny_keccak](https://docs.rs/tiny-keccak/1.4.2/tiny_keccak/) library. +* HKDF: HMAC-based Extract-and-Expand Key Derivation Function (HKDF) based on [RFC 5869](https://tools.ietf.org/html/rfc5869). It is used to generate keys from a salt (optional), seed, and application-info (optional). +* traits.rs introduces new abstractions for the crypto API. +* Ed25519 performs signatures using the new API design based on [ed25519-dalek](https://docs.rs/ed25519-dalek/1.0.0-pre.1/ed25519_dalek/) library with additional security checks (e.g. for malleability). +* X25519 to perform key exchanges. It is used to secure communications between validators via the [Noise Protocol Framework](http://www.noiseprotocol.org/noise.html). It is based on the x25519-dalek library. + +## How is this module organized? +``` + crypto/src + ├── hash.rs # Hash function (SHA-3) + ├── hkdf.rs # HKDF implementation (HMAC-based Extract-and-Expand Key Derivation Function based on RFC 5869) + ├── macros/ # Derivations for SilentDebug and SilentDisplay + ├── utils.rs # Serialization utility functions + ├── lib.rs + ├── ed25519.rs # Ed25519 implementation of the signing/verification API in traits.rs + ├── multi_ed25519.rs # MultiEd25519 implementation of the signing/verification API in traits.rs + ├── x25519.rs # X25519 wrapper + ├── test_utils.rs + ├── traits.rs # New API design and the necessary abstractions + └── unit_tests/ # Tests +``` + +Note: This crate historically had support for BLS12381, ECVRF, and SlIP-0010, though were removed due to lack of use. The last git revision before there removal is 00301524. diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/benches/ed25519.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/benches/ed25519.rs new file mode 100644 index 000000000..7c176c552 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/benches/ed25519.rs @@ -0,0 +1,34 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#[macro_use] +extern crate criterion; + +use criterion::Criterion; +use diem_crypto_derive::{BCSCryptoHash, CryptoHasher}; +use rand::{prelude::ThreadRng, thread_rng}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, CryptoHasher, BCSCryptoHash, Serialize, Deserialize)] +pub struct TestDiemCrypto(pub String); + +use diem_crypto::{ + ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature}, + traits::{Signature, SigningKey, Uniform}, +}; + +fn verify(c: &mut Criterion) { + let mut csprng: ThreadRng = thread_rng(); + let priv_key = Ed25519PrivateKey::generate(&mut csprng); + let pub_key: Ed25519PublicKey = (&priv_key).into(); + let msg = TestDiemCrypto("".to_string()); + let sig: Ed25519Signature = priv_key.sign(&msg); + + c.bench_function("Ed25519 signature verification", move |b| { + b.iter(|| sig.verify(&msg, &pub_key)) + }); +} + +criterion_group!(ed25519_benches, verify); +criterion_main!(ed25519_benches); diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/benches/noise.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/benches/noise.rs new file mode 100644 index 000000000..2a2186b36 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/benches/noise.rs @@ -0,0 +1,132 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Don't forget to run this benchmark with AES-NI enable. +//! You can do this by building with the following flags: +//! `RUSTFLAGS="-Ctarget-cpu=skylake -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3"`. +//! + +#[macro_use] +extern crate criterion; + +use criterion::{Criterion, Throughput}; +use diem_crypto::{ + noise::{handshake_init_msg_len, handshake_resp_msg_len, NoiseConfig, AES_GCM_TAGLEN}, + test_utils::TEST_SEED, + x25519, Uniform as _, ValidCryptoMaterial as _, +}; +use rand::SeedableRng; +use std::convert::TryFrom as _; + +const MSG_SIZE: usize = 4096; + +fn benchmarks(c: &mut Criterion) { + // bench the handshake + let mut group = c.benchmark_group("handshake"); + group.throughput(Throughput::Elements(1)); + group.bench_function("xx", |b| { + // setup keys first + let mut rng = ::rand::rngs::StdRng::from_seed(TEST_SEED); + let initiator_static = x25519::PrivateKey::generate(&mut rng); + let initiator_static = initiator_static.to_bytes(); + let responder_static = x25519::PrivateKey::generate(&mut rng); + let responder_public = responder_static.public_key(); + let responder_static = responder_static.to_bytes(); + + let mut first_message = [0u8; handshake_init_msg_len(0)]; + let mut second_message = [0u8; handshake_init_msg_len(0)]; + + b.iter(|| { + let initiator_static = + x25519::PrivateKey::try_from(initiator_static.clone().as_slice()).unwrap(); + let responder_static = + x25519::PrivateKey::try_from(responder_static.clone().as_slice()).unwrap(); + + let initiator = NoiseConfig::new(initiator_static); + let responder = NoiseConfig::new(responder_static); + + let initiator_state = initiator + .initiate_connection( + &mut rng, + b"prologue", + responder_public, + None, + &mut first_message, + ) + .unwrap(); + + let _ = responder + .respond_to_client_and_finalize( + &mut rng, + b"prologue", + &first_message, + None, + &mut second_message, + ) + .unwrap(); + let _ = initiator + .finalize_connection(initiator_state, &second_message) + .unwrap(); + }) + }); + group.finish(); + + let mut transport_group = c.benchmark_group("transport"); + transport_group.throughput(Throughput::Bytes(MSG_SIZE as u64 * 2)); + transport_group.bench_function("AES-GCM throughput", |b| { + let mut buffer_msg = [0u8; MSG_SIZE * 2]; + + // setup keys first + let mut rng = ::rand::rngs::StdRng::from_seed(TEST_SEED); + let initiator_static = x25519::PrivateKey::generate(&mut rng); + let responder_static = x25519::PrivateKey::generate(&mut rng); + let responder_public = responder_static.public_key(); + + // handshake first + let initiator = NoiseConfig::new(initiator_static); + let responder = NoiseConfig::new(responder_static); + + let mut first_message = [0u8; handshake_init_msg_len(0)]; + let mut second_message = [0u8; handshake_resp_msg_len(0)]; + + let initiator_state = initiator + .initiate_connection( + &mut rng, + b"prologue", + responder_public, + None, + &mut first_message, + ) + .unwrap(); + let (_, mut responder_session) = responder + .respond_to_client_and_finalize( + &mut rng, + b"prologue", + &first_message, + None, + &mut second_message, + ) + .unwrap(); + let (_, mut initiator_session) = initiator + .finalize_connection(initiator_state, &second_message) + .unwrap(); + + // bench throughput post-handshake + b.iter(move || { + let auth_tag = initiator_session + .write_message_in_place(&mut buffer_msg[..MSG_SIZE]) + .expect("session should not be closed"); + + buffer_msg[MSG_SIZE..MSG_SIZE + AES_GCM_TAGLEN].copy_from_slice(&auth_tag); + + let _plaintext = responder_session + .read_message_in_place(&mut buffer_msg[..MSG_SIZE + AES_GCM_TAGLEN]) + .expect("session should not be closed"); + }) + }); + transport_group.finish(); +} + +criterion_group!(benches, benchmarks); +criterion_main!(benches); diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/compat.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/compat.rs new file mode 100644 index 000000000..3151db781 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/compat.rs @@ -0,0 +1,63 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Wrapper structs for types that need [RustCrypto](https://github.com/RustCrypto) +//! traits implemented. + +use digest::{ + consts::{U136, U32}, + generic_array::GenericArray, + BlockInput, Digest, FixedOutput, Reset, Update, +}; +use tiny_keccak::{Hasher, Sha3}; + +/// A wrapper for [`tiny_keccak::Sha3::v256`] that +/// implements RustCrypto [`digest`] traits [`BlockInput`], [`Update`], [`Reset`], +/// and [`FixedOutput`]. Consequently, this wrapper can be used in RustCrypto +/// APIs that require a hash function (usually something that impls [`Digest`]). +#[derive(Clone)] +pub struct Sha3_256(Sha3); + +// ensure that we impl all of the sub-traits required for the Digest trait alias +static_assertions::assert_impl_all!(Sha3_256: Digest); + +impl Default for Sha3_256 { + #[inline] + fn default() -> Self { + Self(Sha3::v256()) + } +} + +impl BlockInput for Sha3_256 { + type BlockSize = U136; +} + +impl Update for Sha3_256 { + #[inline] + fn update(&mut self, data: impl AsRef<[u8]>) { + self.0.update(data.as_ref()); + } +} + +impl Reset for Sha3_256 { + #[inline] + fn reset(&mut self) { + *self = Self::default(); + } +} + +impl FixedOutput for Sha3_256 { + type OutputSize = U32; + + #[inline] + fn finalize_into(self, out: &mut GenericArray) { + self.0.finalize(out.as_mut()); + } + + #[inline] + fn finalize_into_reset(&mut self, out: &mut GenericArray) { + self.clone().finalize_into(out); + Reset::reset(self) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/ed25519.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/ed25519.rs new file mode 100644 index 000000000..498b3bbe1 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/ed25519.rs @@ -0,0 +1,557 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides an API for the PureEdDSA signature scheme over the ed25519 twisted +//! Edwards curve as defined in [RFC8032](https://tools.ietf.org/html/rfc8032). +//! +//! Signature verification also checks and rejects non-canonical signatures. +//! +//! # Examples +//! +//! ``` +//! use diem_crypto_derive::{CryptoHasher, BCSCryptoHash}; +//! use diem_crypto::{ +//! ed25519::*, +//! traits::{Signature, SigningKey, Uniform}, +//! }; +//! use rand::{rngs::StdRng, SeedableRng}; +//! use serde::{Serialize, Deserialize}; +//! +//! #[derive(Serialize, Deserialize, CryptoHasher, BCSCryptoHash)] +//! pub struct TestCryptoDocTest(String); +//! let message = TestCryptoDocTest("Test message".to_string()); +//! +//! let mut rng: StdRng = SeedableRng::from_seed([0; 32]); +//! let private_key = Ed25519PrivateKey::generate(&mut rng); +//! let public_key: Ed25519PublicKey = (&private_key).into(); +//! let signature = private_key.sign(&message); +//! assert!(signature.verify(&message, &public_key).is_ok()); +//! ``` +//! **Note**: The above example generates a private key using a private function intended only for +//! testing purposes. Production code should find an alternate means for secure key generation. +#![allow(clippy::integer_arithmetic)] + +use crate::{ + hash::{CryptoHash, CryptoHasher}, + traits::*, +}; +use anyhow::{anyhow, Result}; +use core::convert::TryFrom; +use diem_crypto_derive::{DeserializeKey, SerializeKey, SilentDebug, SilentDisplay}; +pub use ed25519_dalek; +use mirai_annotations::*; +use serde::Serialize; +use std::{cmp::Ordering, fmt}; + +/// The length of the Ed25519PrivateKey +pub const ED25519_PRIVATE_KEY_LENGTH: usize = ed25519_dalek::SECRET_KEY_LENGTH; +/// The length of the Ed25519PublicKey +pub const ED25519_PUBLIC_KEY_LENGTH: usize = ed25519_dalek::PUBLIC_KEY_LENGTH; +/// The length of the Ed25519Signature +pub const ED25519_SIGNATURE_LENGTH: usize = ed25519_dalek::SIGNATURE_LENGTH; + +/// The order of ed25519 as defined in [RFC8032](https://tools.ietf.org/html/rfc8032). +const L: [u8; 32] = [ + 0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +]; + +/// An Ed25519 private key +#[derive(DeserializeKey, SerializeKey, SilentDebug, SilentDisplay)] +pub struct Ed25519PrivateKey(ed25519_dalek::SecretKey); + +#[cfg(feature = "assert-private-keys-not-cloneable")] +static_assertions::assert_not_impl_any!(Ed25519PrivateKey: Clone); + +#[cfg(any(test, feature = "cloneable-private-keys"))] +impl Clone for Ed25519PrivateKey { + fn clone(&self) -> Self { + let serialized: &[u8] = &(self.to_bytes()); + Ed25519PrivateKey::try_from(serialized).unwrap() + } +} + +/// An Ed25519 public key +#[derive(DeserializeKey, Clone, SerializeKey)] +pub struct Ed25519PublicKey(ed25519_dalek::PublicKey); + +#[cfg(mirai)] +use crate::tags::ValidatedPublicKeyTag; +#[cfg(not(mirai))] +struct ValidatedPublicKeyTag {} + +/// An Ed25519 signature +#[derive(DeserializeKey, Clone, SerializeKey)] +pub struct Ed25519Signature(ed25519_dalek::Signature); + +impl Ed25519PrivateKey { + /// The length of the Ed25519PrivateKey + pub const LENGTH: usize = ed25519_dalek::SECRET_KEY_LENGTH; + + /// Serialize an Ed25519PrivateKey. + pub fn to_bytes(&self) -> [u8; ED25519_PRIVATE_KEY_LENGTH] { + self.0.to_bytes() + } + + /// Deserialize an Ed25519PrivateKey without any validation checks apart from expected key size. + fn from_bytes_unchecked( + bytes: &[u8], + ) -> std::result::Result { + match ed25519_dalek::SecretKey::from_bytes(bytes) { + Ok(dalek_secret_key) => Ok(Ed25519PrivateKey(dalek_secret_key)), + Err(_) => Err(CryptoMaterialError::DeserializationError), + } + } + + /// Private function aimed at minimizing code duplication between sign + /// methods of the SigningKey implementation. This should remain private. + fn sign_arbitrary_message(&self, message: &[u8]) -> Ed25519Signature { + let secret_key: &ed25519_dalek::SecretKey = &self.0; + let public_key: Ed25519PublicKey = self.into(); + let expanded_secret_key: ed25519_dalek::ExpandedSecretKey = + ed25519_dalek::ExpandedSecretKey::from(secret_key); + let sig = expanded_secret_key.sign(message.as_ref(), &public_key.0); + Ed25519Signature(sig) + } +} + +impl Ed25519PublicKey { + /// Serialize an Ed25519PublicKey. + pub fn to_bytes(&self) -> [u8; ED25519_PUBLIC_KEY_LENGTH] { + self.0.to_bytes() + } + + /// Deserialize an Ed25519PublicKey without any validation checks apart from expected key size. + pub(crate) fn from_bytes_unchecked( + bytes: &[u8], + ) -> std::result::Result { + match ed25519_dalek::PublicKey::from_bytes(bytes) { + Ok(dalek_public_key) => Ok(Ed25519PublicKey(dalek_public_key)), + Err(_) => Err(CryptoMaterialError::DeserializationError), + } + } + + /// Deserialize an Ed25519PublicKey from its representation as an x25519 + /// public key, along with an indication of sign. This is meant to + /// compensate for the poor key storage capabilities of key management + /// solutions, and NOT to promote double usage of keys under several + /// schemes, which would lead to BAD vulnerabilities. + /// + /// Arguments: + /// - `x25519_bytes`: bit representation of a public key in clamped + /// Montgomery form, a.k.a. the x25519 public key format. + /// - `negative`: whether to interpret the given point as a negative point, + /// as the Montgomery form erases the sign byte. By XEdDSA + /// convention, if you expect to ever convert this back to an + /// x25519 public key, you should pass `false` for this + /// argument. + #[cfg(test)] + pub(crate) fn from_x25519_public_bytes( + x25519_bytes: &[u8], + negative: bool, + ) -> Result { + if x25519_bytes.len() != 32 { + return Err(CryptoMaterialError::DeserializationError); + } + let key_bits = { + let mut bits = [0u8; 32]; + bits.copy_from_slice(x25519_bytes); + bits + }; + let mtg_point = curve25519_dalek::montgomery::MontgomeryPoint(key_bits); + let sign = u8::from(negative); + let ed_point = mtg_point + .to_edwards(sign) + .ok_or(CryptoMaterialError::DeserializationError)?; + Ed25519PublicKey::try_from(&ed_point.compress().as_bytes()[..]) + } +} + +impl Ed25519Signature { + /// The length of the Ed25519Signature + pub const LENGTH: usize = ed25519_dalek::SIGNATURE_LENGTH; + + /// Serialize an Ed25519Signature. + pub fn to_bytes(&self) -> [u8; ED25519_SIGNATURE_LENGTH] { + self.0.to_bytes() + } + + /// Deserialize an Ed25519Signature without any validation checks (malleability) + /// apart from expected key size. + pub(crate) fn from_bytes_unchecked( + bytes: &[u8], + ) -> std::result::Result { + match ed25519_dalek::Signature::try_from(bytes) { + Ok(dalek_signature) => Ok(Ed25519Signature(dalek_signature)), + Err(_) => Err(CryptoMaterialError::DeserializationError), + } + } + + /// return an all-zero signature (for test only) + #[cfg(any(test, feature = "fuzzing"))] + pub fn dummy_signature() -> Self { + Self::from_bytes_unchecked(&[0u8; Self::LENGTH]).unwrap() + } + + /// Check for correct size and third-party based signature malleability issues. + /// This method is required to ensure that given a valid signature for some message under some + /// key, an attacker cannot produce another valid signature for the same message and key. + /// + /// According to [RFC8032](https://tools.ietf.org/html/rfc8032), signatures comprise elements + /// {R, S} and we should enforce that S is of canonical form (smaller than L, where L is the + /// order of edwards25519 curve group) to prevent signature malleability. Without this check, + /// one could add a multiple of L into S and still pass signature verification, resulting in + /// a distinct yet valid signature. + /// + /// This method does not check the R component of the signature, because R is hashed during + /// signing and verification to compute h = H(ENC(R) || ENC(A) || M), which means that a + /// third-party cannot modify R without being detected. + /// + /// Note: It's true that malicious signers can already produce varying signatures by + /// choosing a different nonce, so this method protects against malleability attacks performed + /// by a non-signer. + pub fn check_malleability(bytes: &[u8]) -> std::result::Result<(), CryptoMaterialError> { + if bytes.len() != ED25519_SIGNATURE_LENGTH { + return Err(CryptoMaterialError::WrongLengthError); + } + if !check_s_lt_l(&bytes[32..]) { + return Err(CryptoMaterialError::CanonicalRepresentationError); + } + Ok(()) + } +} + +/////////////////////// +// PrivateKey Traits // +/////////////////////// + +impl PrivateKey for Ed25519PrivateKey { + type PublicKeyMaterial = Ed25519PublicKey; +} + +impl SigningKey for Ed25519PrivateKey { + type SignatureMaterial = Ed25519Signature; + type VerifyingKeyMaterial = Ed25519PublicKey; + + fn sign(&self, message: &T) -> Ed25519Signature { + Ed25519PrivateKey::sign_arbitrary_message(self, signing_message(message).as_ref()) + } + + #[cfg(any(test, feature = "fuzzing"))] + fn sign_arbitrary_message(&self, message: &[u8]) -> Ed25519Signature { + Ed25519PrivateKey::sign_arbitrary_message(self, message) + } +} + +impl Uniform for Ed25519PrivateKey { + fn generate(rng: &mut R) -> Self + where + R: ::rand::RngCore + ::rand::CryptoRng, + { + Ed25519PrivateKey(ed25519_dalek::SecretKey::generate(rng)) + } +} + +impl PartialEq for Ed25519PrivateKey { + fn eq(&self, other: &Self) -> bool { + self.to_bytes() == other.to_bytes() + } +} + +impl Eq for Ed25519PrivateKey {} + +// We could have a distinct kind of validation for the PrivateKey, for +// ex. checking the derived PublicKey is valid? +impl TryFrom<&[u8]> for Ed25519PrivateKey { + type Error = CryptoMaterialError; + + /// Deserialize an Ed25519PrivateKey. This method will also check for key validity. + fn try_from(bytes: &[u8]) -> std::result::Result { + // Note that the only requirement is that the size of the key is 32 bytes, something that + // is already checked during deserialization of ed25519_dalek::SecretKey + // Also, the underlying ed25519_dalek implementation ensures that the derived public key + // is safe and it will not lie in a small-order group, thus no extra check for PublicKey + // validation is required. + Ed25519PrivateKey::from_bytes_unchecked(bytes) + } +} + +impl Length for Ed25519PrivateKey { + fn length(&self) -> usize { + Self::LENGTH + } +} + +impl ValidCryptoMaterial for Ed25519PrivateKey { + fn to_bytes(&self) -> Vec { + self.to_bytes().to_vec() + } +} + +impl Genesis for Ed25519PrivateKey { + fn genesis() -> Self { + let mut buf = [0u8; ED25519_PRIVATE_KEY_LENGTH]; + buf[ED25519_PRIVATE_KEY_LENGTH - 1] = 1; + Self::try_from(buf.as_ref()).unwrap() + } +} + +////////////////////// +// PublicKey Traits // +////////////////////// + +// Implementing From<&PrivateKey<...>> allows to derive a public key in a more elegant fashion +impl From<&Ed25519PrivateKey> for Ed25519PublicKey { + fn from(private_key: &Ed25519PrivateKey) -> Self { + let secret: &ed25519_dalek::SecretKey = &private_key.0; + let public: ed25519_dalek::PublicKey = secret.into(); + Ed25519PublicKey(public) + } +} + +// We deduce PublicKey from this +impl PublicKey for Ed25519PublicKey { + type PrivateKeyMaterial = Ed25519PrivateKey; +} + +impl std::hash::Hash for Ed25519PublicKey { + fn hash(&self, state: &mut H) { + let encoded_pubkey = self.to_bytes(); + state.write(&encoded_pubkey); + } +} + +// Those are required by the implementation of hash above +impl PartialEq for Ed25519PublicKey { + fn eq(&self, other: &Ed25519PublicKey) -> bool { + self.to_bytes() == other.to_bytes() + } +} + +impl Eq for Ed25519PublicKey {} + +// We deduce VerifyingKey from pointing to the signature material +// we get the ability to do `pubkey.validate(msg, signature)` +impl VerifyingKey for Ed25519PublicKey { + type SignatureMaterial = Ed25519Signature; + type SigningKeyMaterial = Ed25519PrivateKey; +} + +impl fmt::Display for Ed25519PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex::encode(self.0.as_bytes())) + } +} + +impl fmt::Debug for Ed25519PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Ed25519PublicKey({})", self) + } +} + +impl TryFrom<&[u8]> for Ed25519PublicKey { + type Error = CryptoMaterialError; + + /// Deserialize an Ed25519PublicKey. This method will also check for key validity, for instance + /// it will only deserialize keys that are safe against small subgroup attacks. + fn try_from(bytes: &[u8]) -> std::result::Result { + // We need to access the Edwards point which is not directly accessible from + // ed25519_dalek::PublicKey, so we need to do some custom deserialization. + if bytes.len() != ED25519_PUBLIC_KEY_LENGTH { + return Err(CryptoMaterialError::WrongLengthError); + } + + let mut bits = [0u8; ED25519_PUBLIC_KEY_LENGTH]; + bits.copy_from_slice(&bytes[..ED25519_PUBLIC_KEY_LENGTH]); + + let compressed = curve25519_dalek::edwards::CompressedEdwardsY(bits); + let point = compressed + .decompress() + .ok_or(CryptoMaterialError::DeserializationError)?; + + // Check if the point lies on a small subgroup. This is required + // when using curves with a small cofactor (in ed25519, cofactor = 8). + if point.is_small_order() { + return Err(CryptoMaterialError::SmallSubgroupError); + } + + // Unfortunately, tuple struct `PublicKey` is private so we cannot + // Ok(Ed25519PublicKey(ed25519_dalek::PublicKey(compressed, point))) + // and we have to again invoke deserialization. + let public_key = Ed25519PublicKey::from_bytes_unchecked(bytes)?; + add_tag!(&public_key, ValidatedPublicKeyTag); // This key has gone through validity checks. + Ok(public_key) + } +} + +impl Length for Ed25519PublicKey { + fn length(&self) -> usize { + ED25519_PUBLIC_KEY_LENGTH + } +} + +impl ValidCryptoMaterial for Ed25519PublicKey { + fn to_bytes(&self) -> Vec { + self.0.to_bytes().to_vec() + } +} + +////////////////////// +// Signature Traits // +////////////////////// + +impl Signature for Ed25519Signature { + type SigningKeyMaterial = Ed25519PrivateKey; + type VerifyingKeyMaterial = Ed25519PublicKey; + + /// Verifies that the provided signature is valid for the provided + /// message, according to the RFC8032 algorithm. This strict verification performs the + /// recommended check of 5.1.7 §3, on top of the required RFC8032 verifications. + fn verify( + &self, + message: &T, + public_key: &Ed25519PublicKey, + ) -> Result<()> { + // Public keys should be validated to be safe against small subgroup attacks, etc. + precondition!(has_tag!(public_key, ValidatedPublicKeyTag)); + let mut bytes = ::seed().to_vec(); + bcs::serialize_into(&mut bytes, &message) + .map_err(|_| CryptoMaterialError::SerializationError)?; + Self::verify_arbitrary_msg(self, &bytes, public_key) + } + + /// Checks that `self` is valid for an arbitrary &[u8] `message` using `public_key`. + /// Outside of this crate, this particular function should only be used for native signature + /// verification in move + fn verify_arbitrary_msg(&self, message: &[u8], public_key: &Ed25519PublicKey) -> Result<()> { + // Public keys should be validated to be safe against small subgroup attacks, etc. + precondition!(has_tag!(public_key, ValidatedPublicKeyTag)); + Ed25519Signature::check_malleability(&self.to_bytes())?; + + public_key + .0 + .verify_strict(message, &self.0) + .map_err(|e| anyhow!("{}", e)) + .and(Ok(())) + } + + fn to_bytes(&self) -> Vec { + self.0.to_bytes().to_vec() + } + + /// Batch signature verification as described in the original EdDSA article + /// by Bernstein et al. "High-speed high-security signatures". Current implementation works for + /// signatures on the same message and it checks for malleability. + #[cfg(feature = "batch")] + fn batch_verify( + message: &T, + keys_and_signatures: Vec<(Self::VerifyingKeyMaterial, Self)>, + ) -> Result<()> { + for (_, sig) in keys_and_signatures.iter() { + Ed25519Signature::check_malleability(&sig.to_bytes())? + } + let mut message_bytes = ::seed().to_vec(); + bcs::serialize_into(&mut message_bytes, &message) + .map_err(|_| CryptoMaterialError::SerializationError)?; + + let batch_argument = keys_and_signatures + .iter() + .map(|(key, signature)| (key.0, signature.0)); + let (dalek_public_keys, dalek_signatures): (Vec<_>, Vec<_>) = batch_argument.unzip(); + let message_ref = &(&message_bytes)[..]; + // The original batching algorithm works for different messages and it expects as many + // messages as the number of signatures. In our case, we just populate the same + // message to meet dalek's api requirements. + let messages = vec![message_ref; dalek_signatures.len()]; + ed25519_dalek::verify_batch(&messages[..], &dalek_signatures[..], &dalek_public_keys[..]) + .map_err(|e| anyhow!("{}", e))?; + Ok(()) + } +} + +impl Length for Ed25519Signature { + fn length(&self) -> usize { + ED25519_SIGNATURE_LENGTH + } +} + +impl ValidCryptoMaterial for Ed25519Signature { + fn to_bytes(&self) -> Vec { + self.to_bytes().to_vec() + } +} + +impl std::hash::Hash for Ed25519Signature { + fn hash(&self, state: &mut H) { + let encoded_signature = self.to_bytes(); + state.write(&encoded_signature); + } +} + +impl TryFrom<&[u8]> for Ed25519Signature { + type Error = CryptoMaterialError; + + fn try_from(bytes: &[u8]) -> std::result::Result { + Ed25519Signature::check_malleability(bytes)?; + Ed25519Signature::from_bytes_unchecked(bytes) + } +} + +// Those are required by the implementation of hash above +impl PartialEq for Ed25519Signature { + fn eq(&self, other: &Ed25519Signature) -> bool { + self.to_bytes()[..] == other.to_bytes()[..] + } +} + +impl Eq for Ed25519Signature {} + +impl fmt::Display for Ed25519Signature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex::encode(&self.0.to_bytes()[..])) + } +} + +impl fmt::Debug for Ed25519Signature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Ed25519Signature({})", self) + } +} + +/// Check if S < L to capture invalid signatures. +fn check_s_lt_l(s: &[u8]) -> bool { + for i in (0..32).rev() { + match s[i].cmp(&L[i]) { + Ordering::Less => return true, + Ordering::Greater => return false, + _ => {}, + } + } + // As this stage S == L which implies a non canonical S. + false +} + +#[cfg(any(test, feature = "fuzzing"))] +use crate::test_utils::{self, KeyPair}; + +/// Produces a uniformly random ed25519 keypair from a seed +#[cfg(any(test, feature = "fuzzing"))] +pub fn keypair_strategy() -> impl Strategy> { + test_utils::uniform_keypair_strategy::() +} + +#[cfg(any(test, feature = "fuzzing"))] +use proptest::prelude::*; + +#[cfg(any(test, feature = "fuzzing"))] +impl proptest::arbitrary::Arbitrary for Ed25519PublicKey { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + crate::test_utils::uniform_keypair_strategy::() + .prop_map(|v| v.public_key) + .boxed() + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/error.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/error.rs new file mode 100644 index 000000000..3bc914d96 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/error.rs @@ -0,0 +1,7 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Rexport the error types needed for the various crypto traits + +pub use anyhow::{bail, Error}; diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/hash.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/hash.rs new file mode 100644 index 000000000..3768c1f83 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/hash.rs @@ -0,0 +1,694 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module defines traits and implementations of +//! [cryptographic hash functions](https://en.wikipedia.org/wiki/Cryptographic_hash_function) +//! for the Diem project. +//! +//! It is designed to help authors protect against two types of real world attacks: +//! +//! 1. **Semantic Ambiguity**: imagine that Alice has a private key and is using +//! two different applications, X and Y. X asks Alice to sign a message saying +//! "I am Alice". Alice accepts to sign this message in the context of X. However, +//! unbeknownst to Alice, in application Y, messages beginning with the letter "I" +//! represent transfers. " am " represents a transfer of 500 coins and "Alice" +//! can be interpreted as a destination address. When Alice signed the message she +//! needed to be aware of how other applications might interpret that message. +//! +//! 2. **Format Ambiguity**: imagine a program that hashes a pair of strings. +//! To hash the strings `a` and `b` it hashes `a + "||" + b`. The pair of +//! strings `a="foo||", b = "bar"` and `a="foo", b = "||bar"` result in the +//! same input to the hash function and therefore the same hash. This +//! creates a collision. +//! +//! Regarding (1), this library makes it easy for Diem developers to create as +//! many new "hashable" Rust types as needed so that each Rust type hashed and signed +//! in Diem has a unique meaning, that is, unambiguously captures the intent of a signer. +//! +//! Regarding (2), this library provides the `CryptoHasher` abstraction to easily manage +//! cryptographic seeds for hashing. Hashing seeds aim to ensure that +//! the hashes of values of a given type `MyNewStruct` never collide with hashes of values +//! from another type. +//! +//! Finally, to prevent format ambiguity within a same type `MyNewStruct` and facilitate protocol +//! specifications, we use [Binary Canonical Serialization (BCS)](https://docs.rs/bcs/) +//! as the recommended solution to write Rust values into a hasher. +//! +//! # Quick Start +//! +//! To obtain a `hash()` method for any new type `MyNewStruct`, it is (strongly) recommended to +//! use the derive macros of `serde` and `diem_crypto_derive` as follows: +//! ``` +//! use diem_crypto::hash::CryptoHash; +//! use diem_crypto_derive::{CryptoHasher, BCSCryptoHash}; +//! use serde::{Deserialize, Serialize}; +//! #[derive(Serialize, Deserialize, CryptoHasher, BCSCryptoHash)] +//! struct MyNewStruct { /*...*/ } +//! +//! let value = MyNewStruct { /*...*/ }; +//! value.hash(); +//! ``` +//! +//! Under the hood, this will generate a new implementation `MyNewStructHasher` for the trait +//! `CryptoHasher` and implement the trait `CryptoHash` for `MyNewStruct` using BCS. +//! +//! # Implementing New Hashers +//! +//! The trait `CryptoHasher` captures the notion of a pre-seeded hash function, aka a "hasher". +//! New implementations can be defined in two ways. +//! +//! ## Derive macro (recommended) +//! +//! For any new structure `MyNewStruct` that needs to be hashed, it is recommended to simply +//! use the derive macro [`CryptoHasher`](https://doc.rust-lang.org/reference/procedural-macros.html). +//! +//! ``` +//! use diem_crypto_derive::CryptoHasher; +//! use serde::Deserialize; +//! #[derive(Deserialize, CryptoHasher)] +//! #[serde(rename = "OptionalCustomSerdeName")] +//! struct MyNewStruct { /*...*/ } +//! ``` +//! +//! The macro `CryptoHasher` will define a hasher automatically called `MyNewStructHasher`, and derive a salt +//! using the name of the type as seen by the Serde library. In the example above, this name +//! was changed using the Serde parameter `rename`: the salt will be based on the value `OptionalCustomSerdeName` +//! instead of the default name `MyNewStruct`. +//! +//! ## Customized hashers +//! +//! **IMPORTANT:** Do NOT use this for new code unless you know what you are doing. +//! +//! This library also provides a few customized hashers defined in the code as follows: +//! +//! ``` +//! # // To get around that there's no way to doc-test a non-exported macro: +//! # macro_rules! define_hasher { ($e:expr) => () } +//! define_hasher! { (MyNewDataHasher, MY_NEW_DATA_HASHER, MY_NEW_DATA_SEED, b"MyUniqueSaltString") } +//! ``` +//! +//! # Using a hasher directly +//! +//! **IMPORTANT:** Do NOT use this for new code unless you know what you are doing. +//! +//! ``` +//! use diem_crypto::hash::{CryptoHasher, TestOnlyHasher}; +//! +//! let mut hasher = TestOnlyHasher::default(); +//! hasher.update("Test message".as_bytes()); +//! let hash_value = hasher.finish(); +//! ``` +#![allow(clippy::integer_arithmetic)] +use bytes::Bytes; +use hex::FromHex; +use mirai_annotations::*; +use once_cell::sync::{Lazy, OnceCell}; +#[cfg(any(test, feature = "fuzzing"))] +use proptest_derive::Arbitrary; +use rand::{rngs::OsRng, Rng}; +use serde::{de, ser}; +use std::{ + self, + convert::{AsRef, TryFrom}, + fmt, + str::FromStr, +}; +use tiny_keccak::{Hasher, Sha3}; + +/// A prefix used to begin the salt of every diem hashable structure. The salt +/// consists in this global prefix, concatenated with the specified +/// serialization name of the struct. +pub(crate) const DIEM_HASH_PREFIX: &[u8] = b"DIEM::"; + +/// Output value of our hash function. Intentionally opaque for safety and modularity. +#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] +pub struct HashValue { + hash: [u8; HashValue::LENGTH], +} + +impl HashValue { + /// The length of the hash in bytes. + pub const LENGTH: usize = 32; + /// The length of the hash in bits. + pub const LENGTH_IN_BITS: usize = Self::LENGTH * 8; + + /// Create a new [`HashValue`] from a byte array. + pub fn new(hash: [u8; HashValue::LENGTH]) -> Self { + HashValue { hash } + } + + /// Create from a slice (e.g. retrieved from storage). + pub fn from_slice>(bytes: T) -> Result { + <[u8; Self::LENGTH]>::try_from(bytes.as_ref()) + .map_err(|_| HashValueParseError) + .map(Self::new) + } + + /// Dumps into a vector. + pub fn to_vec(&self) -> Vec { + self.hash.to_vec() + } + + /// Creates a zero-initialized instance. + pub const fn zero() -> Self { + HashValue { + hash: [0; HashValue::LENGTH], + } + } + + /// Create a cryptographically random instance. + pub fn random() -> Self { + let mut rng = OsRng; + let hash: [u8; HashValue::LENGTH] = rng.gen(); + HashValue { hash } + } + + /// Creates a random instance with given rng. Useful in unit tests. + pub fn random_with_rng(rng: &mut R) -> Self { + let hash: [u8; HashValue::LENGTH] = rng.gen(); + HashValue { hash } + } + + /// Convenience function that computes a `HashValue` internally equal to + /// the sha3_256 of a byte buffer. It will handle hasher creation, data + /// feeding and finalization. + /// + /// Note this will not result in the `::hash()` for any + /// reasonable struct T, as this computes a sha3 without any ornaments. + pub fn sha3_256_of(buffer: &[u8]) -> Self { + let mut sha3 = Sha3::v256(); + sha3.update(buffer); + HashValue::from_keccak(sha3) + } + + #[cfg(test)] + pub fn from_iter_sha3<'a, I>(buffers: I) -> Self + where + I: IntoIterator, + { + let mut sha3 = Sha3::v256(); + for buffer in buffers { + sha3.update(buffer); + } + HashValue::from_keccak(sha3) + } + + fn as_ref_mut(&mut self) -> &mut [u8] { + &mut self.hash[..] + } + + fn from_keccak(state: Sha3) -> Self { + let mut hash = Self::zero(); + state.finalize(hash.as_ref_mut()); + hash + } + + /// Returns the `index`-th bit in the bytes. + pub fn bit(&self, index: usize) -> bool { + assume!(index < Self::LENGTH_IN_BITS); // assumed precondition + let pos = index / 8; + let bit = 7 - index % 8; + (self.hash[pos] >> bit) & 1 != 0 + } + + /// Returns the `index`-th nibble in the bytes. + pub fn nibble(&self, index: usize) -> u8 { + assume!(index < Self::LENGTH * 2); // assumed precondition + let pos = index / 2; + let shift = if index % 2 == 0 { 4 } else { 0 }; + (self.hash[pos] >> shift) & 0x0F + } + + /// Returns a `HashValueBitIterator` over all the bits that represent this `HashValue`. + pub fn iter_bits(&self) -> HashValueBitIterator<'_> { + HashValueBitIterator::new(self) + } + + /// Constructs a `HashValue` from an iterator of bits. + pub fn from_bit_iter( + iter: impl ExactSizeIterator, + ) -> Result { + if iter.len() != Self::LENGTH_IN_BITS { + return Err(HashValueParseError); + } + + let mut buf = [0; Self::LENGTH]; + for (i, bit) in iter.enumerate() { + if bit { + buf[i / 8] |= 1 << (7 - i % 8); + } + } + Ok(Self::new(buf)) + } + + /// Returns the length of common prefix of `self` and `other` in bits. + pub fn common_prefix_bits_len(&self, other: HashValue) -> usize { + self.iter_bits() + .zip(other.iter_bits()) + .take_while(|(x, y)| x == y) + .count() + } + + /// Full hex representation of a given hash value. + pub fn to_hex(&self) -> String { + format!("{:x}", self) + } + + /// Full hex representation of a given hash value with `0x` prefix. + pub fn to_hex_literal(&self) -> String { + format!("{:#x}", self) + } + + /// Parse a given hex string to a hash value. + pub fn from_hex>(hex: T) -> Result { + <[u8; Self::LENGTH]>::from_hex(hex) + .map_err(|_| HashValueParseError) + .map(Self::new) + } + + /// Create a hash value whose contents are just the given integer. Useful for + /// generating basic mock hash values. + /// + /// Ex: HashValue::from_u64(0x1234) => HashValue([0, .., 0, 0x12, 0x34]) + #[cfg(any(test, feature = "fuzzing"))] + pub fn from_u64(v: u64) -> Self { + let mut hash = [0u8; Self::LENGTH]; + let bytes = v.to_be_bytes(); + hash[Self::LENGTH - bytes.len()..].copy_from_slice(&bytes[..]); + Self::new(hash) + } +} + +impl ser::Serialize for HashValue { + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + if serializer.is_human_readable() { + serializer.serialize_str(&self.to_hex()) + } else { + // In order to preserve the Serde data model and help analysis tools, + // make sure to wrap our value in a container with the same name + // as the original type. + serializer + .serialize_newtype_struct("HashValue", serde_bytes::Bytes::new(&self.hash[..])) + } + } +} + +impl<'de> de::Deserialize<'de> for HashValue { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + if deserializer.is_human_readable() { + let encoded_hash = ::deserialize(deserializer)?; + HashValue::from_hex(encoded_hash.as_str()) + .map_err(::custom) + } else { + // See comment in serialize. + #[derive(::serde::Deserialize)] + #[serde(rename = "HashValue")] + struct Value<'a>(&'a [u8]); + + let value = Value::deserialize(deserializer)?; + Self::from_slice(value.0).map_err(::custom) + } + } +} + +impl Default for HashValue { + fn default() -> Self { + HashValue::zero() + } +} + +impl AsRef<[u8; HashValue::LENGTH]> for HashValue { + fn as_ref(&self) -> &[u8; HashValue::LENGTH] { + &self.hash + } +} + +impl std::ops::Deref for HashValue { + type Target = [u8; Self::LENGTH]; + + fn deref(&self) -> &Self::Target { + &self.hash + } +} + +impl std::ops::Index for HashValue { + type Output = u8; + + fn index(&self, s: usize) -> &u8 { + self.hash.index(s) + } +} + +impl fmt::Binary for HashValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for byte in &self.hash { + write!(f, "{:08b}", byte)?; + } + Ok(()) + } +} + +impl fmt::LowerHex for HashValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if f.alternate() { + write!(f, "0x")?; + } + for byte in &self.hash { + write!(f, "{:02x}", byte)?; + } + Ok(()) + } +} + +impl fmt::Debug for HashValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "HashValue(")?; + ::fmt(self, f)?; + write!(f, ")")?; + Ok(()) + } +} + +/// Will print shortened (4 bytes) hash +impl fmt::Display for HashValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for byte in self.hash.iter().take(4) { + write!(f, "{:02x}", byte)?; + } + Ok(()) + } +} + +impl From for Bytes { + fn from(value: HashValue) -> Bytes { + Bytes::copy_from_slice(value.hash.as_ref()) + } +} + +impl FromStr for HashValue { + type Err = HashValueParseError; + + fn from_str(s: &str) -> Result { + HashValue::from_hex(s) + } +} + +/// Parse error when attempting to construct a HashValue +#[derive(Clone, Copy, Debug)] +pub struct HashValueParseError; + +impl fmt::Display for HashValueParseError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "unable to parse HashValue") + } +} + +impl std::error::Error for HashValueParseError {} + +/// An iterator over `HashValue` that generates one bit for each iteration. +pub struct HashValueBitIterator<'a> { + /// The reference to the bytes that represent the `HashValue`. + hash_bytes: &'a [u8], + pos: std::ops::Range, + // invariant hash_bytes.len() == HashValue::LENGTH; + // invariant pos.end == hash_bytes.len() * 8; +} + +impl<'a> HashValueBitIterator<'a> { + /// Constructs a new `HashValueBitIterator` using given `HashValue`. + fn new(hash_value: &'a HashValue) -> Self { + HashValueBitIterator { + hash_bytes: hash_value.as_ref(), + pos: (0..HashValue::LENGTH_IN_BITS), + } + } + + /// Returns the `index`-th bit in the bytes. + fn get_bit(&self, index: usize) -> bool { + assume!(index < self.pos.end); // assumed precondition + assume!(self.hash_bytes.len() == HashValue::LENGTH); // invariant + assume!(self.pos.end == self.hash_bytes.len() * 8); // invariant + let pos = index / 8; + let bit = 7 - index % 8; + (self.hash_bytes[pos] >> bit) & 1 != 0 + } +} + +impl<'a> std::iter::Iterator for HashValueBitIterator<'a> { + type Item = bool; + + fn next(&mut self) -> Option { + self.pos.next().map(|x| self.get_bit(x)) + } + + fn size_hint(&self) -> (usize, Option) { + self.pos.size_hint() + } +} + +impl<'a> std::iter::DoubleEndedIterator for HashValueBitIterator<'a> { + fn next_back(&mut self) -> Option { + self.pos.next_back().map(|x| self.get_bit(x)) + } +} + +impl<'a> std::iter::ExactSizeIterator for HashValueBitIterator<'a> {} + +/// A type that can be cryptographically hashed to produce a `HashValue`. +/// +/// In most cases, this trait should not be implemented manually but rather derived using +/// the macros `serde::Serialize`, `CryptoHasher`, and `BCSCryptoHash`. +pub trait CryptoHash { + /// The associated `Hasher` type which comes with a unique salt for this type. + type Hasher: CryptoHasher; + + /// Hashes the object and produces a `HashValue`. + fn hash(&self) -> HashValue; +} + +/// A trait for representing the state of a cryptographic hasher. +pub trait CryptoHasher: Default + std::io::Write { + /// the seed used to initialize hashing `Self` before the serialization bytes of the actual value + fn seed() -> &'static [u8; 32]; + + /// Write bytes into the hasher. + fn update(&mut self, bytes: &[u8]); + + /// Finish constructing the [`HashValue`]. + fn finish(self) -> HashValue; + + /// Convenience method to compute the hash of a complete byte slice. + fn hash_all(bytes: &[u8]) -> HashValue { + let mut hasher = Self::default(); + hasher.update(bytes); + hasher.finish() + } +} + +/// The default hasher underlying generated implementations of `CryptoHasher`. +#[doc(hidden)] +#[derive(Clone)] +pub struct DefaultHasher { + state: Sha3, +} + +impl DefaultHasher { + #[doc(hidden)] + /// This function does not return a HashValue in the sense of our usual + /// hashes, but a construction of initial bytes that are fed into any hash + /// provided we're passed a (bcs) serialization name as argument. + pub fn prefixed_hash(buffer: &[u8]) -> [u8; HashValue::LENGTH] { + // The salt is initial material we prefix to actual value bytes for + // domain separation. Its length is variable. + let salt: Vec = [DIEM_HASH_PREFIX, buffer].concat(); + // The seed is a fixed-length hash of the salt, thereby preventing + // suffix attacks on the domain separation bytes. + HashValue::sha3_256_of(&salt[..]).hash + } + + #[doc(hidden)] + pub fn new(typename: &[u8]) -> Self { + let mut state = Sha3::v256(); + if !typename.is_empty() { + state.update(&Self::prefixed_hash(typename)); + } + DefaultHasher { state } + } + + #[doc(hidden)] + pub fn update(&mut self, bytes: &[u8]) { + self.state.update(bytes); + } + + #[doc(hidden)] + pub fn finish(self) -> HashValue { + let mut hasher = HashValue::default(); + self.state.finalize(hasher.as_ref_mut()); + hasher + } +} + +impl fmt::Debug for DefaultHasher { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "DefaultHasher: state = Sha3") + } +} + +macro_rules! define_hasher { + ( + $(#[$attr:meta])* + ($hasher_type: ident, $hasher_name: ident, $seed_name: ident, $salt: expr) + ) => { + + #[derive(Clone, Debug)] + $(#[$attr])* + pub struct $hasher_type(DefaultHasher); + + impl $hasher_type { + fn new() -> Self { + $hasher_type(DefaultHasher::new($salt)) + } + } + + static $hasher_name: Lazy<$hasher_type> = Lazy::new(|| { $hasher_type::new() }); + static $seed_name: OnceCell<[u8; 32]> = OnceCell::new(); + + impl Default for $hasher_type { + fn default() -> Self { + $hasher_name.clone() + } + } + + impl CryptoHasher for $hasher_type { + fn seed() -> &'static [u8;32] { + $seed_name.get_or_init(|| { + DefaultHasher::prefixed_hash($salt) + }) + } + + fn update(&mut self, bytes: &[u8]) { + self.0.update(bytes); + } + + fn finish(self) -> HashValue { + self.0.finish() + } + } + + impl std::io::Write for $hasher_type { + fn write(&mut self, bytes: &[u8]) -> std::io::Result { + self.0.update(bytes); + Ok(bytes.len()) + } + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + } + }; +} + +define_hasher! { + /// The hasher used to compute the hash of an internal node in the transaction accumulator. + ( + TransactionAccumulatorHasher, + TRANSACTION_ACCUMULATOR_HASHER, + TRANSACTION_ACCUMULATOR_SEED, + b"TransactionAccumulator" + ) +} + +define_hasher! { + /// The hasher used to compute the hash of an internal node in the event accumulator. + ( + EventAccumulatorHasher, + EVENT_ACCUMULATOR_HASHER, + EVENT_ACCUMULATOR_SEED, + b"EventAccumulator" + ) +} + +define_hasher! { + /// The hasher used to compute the hash of an internal node in the Sparse Merkle Tree. + ( + SparseMerkleInternalHasher, + SPARSE_MERKLE_INTERNAL_HASHER, + SPARSE_MERKLE_INTERNAL_SEED, + b"SparseMerkleInternal" + ) +} + +define_hasher! { + /// The hasher used to compute the hash of an internal node in the transaction accumulator. + ( + VoteProposalHasher, + VOTE_PROPOSAL_HASHER, + VOTE_PROPOSAL_SEED, + b"VoteProposalHasher" + ) +} + +define_hasher! { + /// The hasher used only for testing. It doesn't have a salt. + (TestOnlyHasher, TEST_ONLY_HASHER, TEST_ONLY_SEED, b"") +} + +fn create_literal_hash(word: &str) -> HashValue { + let mut s = word.as_bytes().to_vec(); + assert!(s.len() <= HashValue::LENGTH); + s.resize(HashValue::LENGTH, 0); + HashValue::from_slice(&s).expect("Cannot fail") +} + +/// Placeholder hash of `Accumulator`. +pub static ACCUMULATOR_PLACEHOLDER_HASH: Lazy = + Lazy::new(|| create_literal_hash("ACCUMULATOR_PLACEHOLDER_HASH")); + +/// Placeholder hash of `SparseMerkleTree`. +pub static SPARSE_MERKLE_PLACEHOLDER_HASH: Lazy = + Lazy::new(|| create_literal_hash("SPARSE_MERKLE_PLACEHOLDER_HASH")); + +/// Block id reserved as the id of parent block of the genesis block. +pub static PRE_GENESIS_BLOCK_ID: Lazy = + Lazy::new(|| create_literal_hash("PRE_GENESIS_BLOCK_ID")); + +/// Genesis block id is used as a parent of the very first block executed by the executor. +pub static GENESIS_BLOCK_ID: Lazy = Lazy::new(|| { + // This maintains the invariant that block.id() == block.hash(), for + // the genesis block and allows us to (de/)serialize it consistently + HashValue::new([ + 0x5E, 0x10, 0xBA, 0xD4, 0x5B, 0x35, 0xED, 0x92, 0x9C, 0xD6, 0xD2, 0xC7, 0x09, 0x8B, 0x13, + 0x5D, 0x02, 0xDD, 0x25, 0x9A, 0xE8, 0x8A, 0x8D, 0x09, 0xF4, 0xEB, 0x5F, 0xBA, 0xE9, 0xA6, + 0xF6, 0xE4, + ]) +}); + +/// Provides a test_only_hash() method that can be used in tests on types that implement +/// `serde::Serialize`. +/// +/// # Example +/// ``` +/// use diem_crypto::hash::TestOnlyHash; +/// +/// b"hello world".test_only_hash(); +/// ``` +pub trait TestOnlyHash { + /// Generates a hash used only for tests. + fn test_only_hash(&self) -> HashValue; +} + +impl TestOnlyHash for T { + fn test_only_hash(&self) -> HashValue { + let bytes = bcs::to_bytes(self).expect("serialize failed during hash."); + let mut hasher = TestOnlyHasher::default(); + hasher.update(&bytes); + hasher.finish() + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/hkdf.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/hkdf.rs new file mode 100644 index 000000000..71ee00942 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/hkdf.rs @@ -0,0 +1,199 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! An implementation of HKDF, the HMAC-based Extract-and-Expand Key Derivation Function for the +//! Diem project based on [RFC 5869](https://tools.ietf.org/html/rfc5869). +//! +//! The key derivation function (KDF) is intended to support a wide range of applications and +//! requirements, and is conservative in its use of cryptographic hash functions. In particular, +//! this implementation is compatible with hash functions that output 256 bits or more, such as +//! SHA256, SHA3-256 and SHA512. +//! +//! HKDF follows the "extract-then-expand" paradigm, where the KDF logically consists of two +//! modules: the first stage takes the input keying material (the seed) and "extracts" from it a +//! fixed-length pseudorandom key, and then the second stage "expands" this key into several +//! additional pseudorandom keys (the output of the KDF). For convenience, a function that runs both +//! steps in a single call is provided. Note that along with an initial high-entropy seed, a user +//! can optionally provide salt and app-info byte-arrays for extra security guarantees and domain +//! separation. +//! +//! # Applications +//! +//! HKDF is intended for use in a wide variety of KDF applications (see [Key derivation function](https://en.wikipedia.org/wiki/Key_derivation_function)), including: +//! a) derivation of keys from an origin high-entropy master seed. This is the recommended approach +//! for generating keys in Diem, especially when a True Random Generator is not available. +//! b) derivation of session keys from a shared Diffie-Hellman value in a key-agreement protocol. +//! c) combining entropy from multiple sources of randomness, such as entropy collected +//! from system events, user's keystrokes, /dev/urandom etc. The combined seed can then be used to +//! generate cryptographic keys for account, network and transaction signing keys among the others. +//! d) hierarchical private key derivation, similarly to Bitcoin's BIP32 protocol for easier key +//! management. +//! e) hybrid key generation that combines a master seed with a PRNG output for extra security +//! guarantees against a master seed leak or low PRNG entropy. +//! +//! # Recommendations +//! +//! **Salt** +//! HKDF can operate with and without random 'salt'. The use of salt adds to the strength of HKDF, +//! ensuring independence between different uses of the hash function, supporting +//! "source-independent" extraction, and strengthening the HKDF use. The salt value should be a +//! random string of the same length as the hash output. A shorter or less random salt value can +//! still make a contribution to the security of the output key material. Salt values should be +//! independent of the input keying material. In particular, an application needs to make sure that +//! salt values are not chosen or manipulated by an attacker. +//! +//! *Application info* +//! Key expansion accepts an optional 'info' value to which the application assigns some meaning. +//! Its objective is to bind the derived key material to application- and context-specific +//! information. For example, 'info' may contain a protocol number, algorithm identifier, +//! child key number (similarly to [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)), etc. The only technical requirement for 'info' is that +//! it be independent of the seed. +//! +//! **Which function to use: extract, expand or both?** +//! Unless absolutely sure of what they are doing, applications should use both steps — if only for +//! the sake of compatibility with the general case. +//! +//! # Example +//! +//! Run HKDF extract-then-expand so as to return 64 bytes, using 'salt', 'seed' and 'info' as +//! inputs. +//! ``` +//! use diem_crypto::hkdf::Hkdf; +//! use sha2::Sha256; +//! +//! // some bytes required for this example. +//! let raw_bytes = [2u8; 10]; +//! // define salt +//! let salt = Some(&raw_bytes[0..4]); +//! // define seed - in production this is recommended to be a 32 bytes or longer random seed. +//! let seed = [3u8; 32]; +//! // define application info +//! let info = Some(&raw_bytes[4..10]); +//! +//! // HKDF extract-then-expand 64-bytes output +//! let derived_bytes = Hkdf::::extract_then_expand(salt, &seed, info, 64); +//! assert_eq!(derived_bytes.unwrap().len(), 64) +//! ``` + +use digest::{ + generic_array::{self, ArrayLength}, + BlockInput, FixedOutput, Reset, Update, +}; +use generic_array::typenum::{IsGreaterOrEqual, True, U32}; +use std::marker::PhantomData; +use thiserror::Error; + +/// Hash function is not supported if its output is less than 32 bits. +type DMinimumSize = U32; + +/// Seed (ikm = initial key material) is not accepted if its size is less than 16 bytes. This is a +/// precautionary measure to prevent HKDF misuse. 128 bits is the minimum accepted seed entropy +/// length in the majority of today's applications to avoid brute forcing. +/// Note that for Ed25519 keys, random seeds of at least 32 bytes are recommended. +const MINIMUM_SEED_LENGTH: usize = 16; + +/// Structure representing the HKDF, capable of HKDF-Extract and HKDF-Expand operations, as defined +/// in RFC 5869. +#[derive(Clone, Debug)] +pub struct Hkdf +where + D: Update + BlockInput + FixedOutput + Reset + Default + Clone, + D::BlockSize: ArrayLength, + D::OutputSize: ArrayLength, + D::OutputSize: IsGreaterOrEqual, +{ + _marker: PhantomData, +} + +impl Hkdf +where + D: Update + BlockInput + FixedOutput + Reset + Default + Clone, + D::BlockSize: ArrayLength + Clone, + D::OutputSize: ArrayLength, + D::OutputSize: IsGreaterOrEqual, +{ + /// The RFC5869 HKDF-Extract operation. + pub fn extract(salt: Option<&[u8]>, ikm: &[u8]) -> Result, HkdfError> { + if ikm.len() < MINIMUM_SEED_LENGTH { + return Err(HkdfError::InvalidSeedLengthError); + } + Ok(Hkdf::::extract_no_ikm_check(salt, ikm)) + } + + fn extract_no_ikm_check(salt: Option<&[u8]>, ikm: &[u8]) -> Vec { + let (arr, _hkdf) = hkdf::Hkdf::::extract(salt, ikm); + arr.to_vec() + } + + /// The RFC5869 HKDF-Expand operation. + pub fn expand(prk: &[u8], info: Option<&[u8]>, length: usize) -> Result, HkdfError> { + // According to RFC5869, MAX_OUTPUT_LENGTH <= 255 * HashLen — which is + // checked below. + // We specifically exclude a zero size length as well. + if length == 0 { + return Err(HkdfError::InvalidOutputLengthError); + } + + let hkdf = + hkdf::Hkdf::::from_prk(prk).map_err(|_| HkdfError::WrongPseudorandomKeyError)?; + let mut okm = vec![0u8; length]; + hkdf.expand(info.unwrap_or(&[]), &mut okm) + // length > D::OutputSize::to_usize() * 255 + .map_err(|_| HkdfError::InvalidOutputLengthError)?; + Ok(okm) + } + + /// HKDF Extract then Expand operation as a single step. + pub fn extract_then_expand( + salt: Option<&[u8]>, + ikm: &[u8], + info: Option<&[u8]>, + length: usize, + ) -> Result, HkdfError> { + let prk = Hkdf::::extract(salt, ikm)?; + Hkdf::::expand(&prk, info, length) + } + + /// CAUTION: This is not recommended because it does not take an ikm (seed) as an input and + /// thus, it is not fully compliant with the HKDF RFC (which always expects a non-zero ikm). + /// Please use `extract_then_expand` instead, unless you know what you are doing. + /// + /// This api is currently required by the Noise protocol [HKDF specs](https://noiseprotocol.org/noise.html#hash-functions). + /// + /// HKDF Extract then Expand operation as a single step, but without an ikm input. + pub fn extract_then_expand_no_ikm( + salt: Option<&[u8]>, + info: Option<&[u8]>, + length: usize, + ) -> Result, HkdfError> { + let prk = Hkdf::::extract_no_ikm_check(salt, &[]); + Hkdf::::expand(&prk, info, length) + } +} + +/// An error type for HKDF key derivation issues. +/// +/// This enum reflects there are various causes of HKDF failures, including: +/// a) requested HKDF output size exceeds the maximum allowed or is zero. +/// b) hash functions outputting less than 32 bits are not supported (i.e., SHA1 is not supported). +/// c) small PRK value in HKDF-Expand according to RFC 5869. +/// d) any other underlying HMAC error. +#[derive(Clone, Debug, PartialEq, Eq, Error)] +pub enum HkdfError { + /// HKDF expand output exceeds the maximum allowed or is zero. + #[error("HKDF expand error - requested output size exceeds the maximum allowed or is zero")] + InvalidOutputLengthError, + /// PRK on HKDF-Expand should not be less than the underlying hash output bits. + #[error( + "HKDF expand error - the pseudorandom key input ('prk' in RFC 5869) \ + is less than the underlying hash output bits" + )] + WrongPseudorandomKeyError, + /// HMAC key related error; unlikely to happen because every key size is accepted in HMAC. + #[error("HMAC key error")] + MACKeyError, + /// HKDF extract input seed should not be less than the minimum accepted. + #[error("HKDF extract error - input seed is too small")] + InvalidSeedLengthError, +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/lib.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/lib.rs new file mode 100644 index 000000000..b7c4679c5 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/lib.rs @@ -0,0 +1,69 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] +#![deny(missing_docs)] +//! This feature gets turned on only if diem-crypto is compiled via MIRAI in a nightly build. +#![cfg_attr(mirai, allow(incomplete_features), feature(const_generics))] + +//! A library supplying various cryptographic primitives +pub mod compat; +pub mod ed25519; +pub mod error; +pub mod hash; +pub mod hkdf; +pub mod multi_ed25519; +pub mod noise; +pub mod test_utils; +pub mod traits; +pub mod validatable; +pub mod x25519; + +#[cfg(test)] +mod unit_tests; + +#[cfg(mirai)] +mod tags; + +pub use self::traits::*; +pub use hash::HashValue; +// Reexport once_cell and serde_name for use in CryptoHasher Derive implementation. +#[doc(hidden)] +pub use once_cell as _once_cell; +#[doc(hidden)] +pub use serde_name as _serde_name; + +// We use formally verified arithmetic +// in maintained forks of the dalek suite of libraries ({curve, ed, +// x}25519-dalek). This is controlled by a feature in the forked crates +// ('fiat_u64_backend'), which we turn on by default. +#[cfg(not(any(feature = "fiat", feature = "u64", feature = "u32")))] +compile_error!( + "no dalek arithmetic backend cargo feature enabled! \ + please enable one of: fiat, u64, u32" +); + +#[cfg(all(feature = "fiat", feature = "u64"))] +compile_error!( + "at most one dalek arithmetic backend cargo feature should be enabled! \ + please enable exactly one of: fiat, u64, u32" +); + +#[cfg(all(feature = "fiat", feature = "u32"))] +compile_error!( + "at most one dalek arithmetic backend cargo feature should be enabled! \ + please enable exactly one of: fiat, u64, u32" +); + +#[cfg(all(feature = "u64", feature = "u32"))] +compile_error!( + "at most one dalek arithmetic backend cargo feature should be enabled! \ + please enable exactly one of: fiat, u64, u32" +); + +// MIRAI's tag analysis makes use of the incomplete const_generics feature, so the module +// containing the definitions of MIRAI tag types should not get compiled in a release build. +// The code below fails a build of the crate if mirai is on but debug_assertions is not. +#[cfg(all(mirai, not(debug_assertions)))] +compile_error!("MIRAI can only be used to compile the crate in a debug build!"); diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/multi_ed25519.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/multi_ed25519.rs new file mode 100644 index 000000000..3c418818b --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/multi_ed25519.rs @@ -0,0 +1,643 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides an API for the accountable threshold multi-sig PureEdDSA signature scheme +//! over the ed25519 twisted Edwards curve as defined in [RFC8032](https://tools.ietf.org/html/rfc8032). +//! +//! Signature verification also checks and rejects non-canonical signatures. + +use crate::{ + ed25519::{ + Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature, ED25519_PRIVATE_KEY_LENGTH, + ED25519_PUBLIC_KEY_LENGTH, ED25519_SIGNATURE_LENGTH, + }, + hash::{CryptoHash, CryptoHasher}, + traits::*, +}; +use anyhow::{anyhow, Result}; +use core::convert::TryFrom; +use diem_crypto_derive::{DeserializeKey, SerializeKey, SilentDebug, SilentDisplay}; +use mirai_annotations::*; +use rand::Rng; +use serde::Serialize; +use std::{convert::TryInto, fmt}; + +const MAX_NUM_OF_KEYS: usize = 32; +const BITMAP_NUM_OF_BYTES: usize = 4; + +/// Vector of private keys in the multi-key Ed25519 structure along with the threshold. +#[derive(DeserializeKey, Eq, PartialEq, SilentDisplay, SilentDebug, SerializeKey)] +pub struct MultiEd25519PrivateKey { + private_keys: Vec, + threshold: u8, +} + +#[cfg(feature = "assert-private-keys-not-cloneable")] +static_assertions::assert_not_impl_any!(MultiEd25519PrivateKey: Clone); + +/// Vector of public keys in the multi-key Ed25519 structure along with the threshold. +#[derive(Clone, DeserializeKey, Eq, PartialEq, SerializeKey)] +pub struct MultiEd25519PublicKey { + public_keys: Vec, + threshold: u8, +} + +#[cfg(mirai)] +use crate::tags::ValidatedPublicKeyTag; +#[cfg(not(mirai))] +struct ValidatedPublicKeyTag {} + +/// Vector of the multi-key signatures along with a 32bit [u8; 4] bitmap required to map signatures +/// with their corresponding public keys. +/// +/// Note that bits are read from left to right. For instance, in the following bitmap +/// [0b0001_0000, 0b0000_0000, 0b0000_0000, 0b0000_0001], the 3rd and 31st positions are set. +#[derive(Clone, DeserializeKey, Eq, PartialEq, SerializeKey)] +pub struct MultiEd25519Signature { + signatures: Vec, + bitmap: [u8; BITMAP_NUM_OF_BYTES], +} + +impl MultiEd25519PrivateKey { + /// Construct a new MultiEd25519PrivateKey. + pub fn new( + private_keys: Vec, + threshold: u8, + ) -> std::result::Result { + let num_of_keys = private_keys.len(); + if threshold == 0 || num_of_keys < threshold as usize { + Err(CryptoMaterialError::ValidationError) + } else if num_of_keys > MAX_NUM_OF_KEYS { + Err(CryptoMaterialError::WrongLengthError) + } else { + Ok(MultiEd25519PrivateKey { + private_keys, + threshold, + }) + } + } + + /// Serialize a MultiEd25519PrivateKey. + pub fn to_bytes(&self) -> Vec { + to_bytes(&self.private_keys, self.threshold) + } +} + +impl MultiEd25519PublicKey { + /// Construct a new MultiEd25519PublicKey. + /// --- Rules --- + /// a) threshold cannot be zero. + /// b) public_keys.len() should be equal to or larger than threshold. + /// c) support up to MAX_NUM_OF_KEYS public keys. + pub fn new( + public_keys: Vec, + threshold: u8, + ) -> std::result::Result { + let num_of_keys = public_keys.len(); + if threshold == 0 || num_of_keys < threshold as usize { + Err(CryptoMaterialError::ValidationError) + } else if num_of_keys > MAX_NUM_OF_KEYS { + Err(CryptoMaterialError::WrongLengthError) + } else { + Ok(MultiEd25519PublicKey { + public_keys, + threshold, + }) + } + } + + /// Getter public_keys + pub fn public_keys(&self) -> &Vec { + &self.public_keys + } + + /// Getter threshold + pub fn threshold(&self) -> &u8 { + &self.threshold + } + + /// Serialize a MultiEd25519PublicKey. + pub fn to_bytes(&self) -> Vec { + to_bytes(&self.public_keys, self.threshold) + } +} + +/////////////////////// +// PrivateKey Traits // +/////////////////////// + +/// Convenient method to create a MultiEd25519PrivateKey from a single Ed25519PrivateKey. +impl From<&Ed25519PrivateKey> for MultiEd25519PrivateKey { + fn from(ed_private_key: &Ed25519PrivateKey) -> Self { + MultiEd25519PrivateKey { + private_keys: vec![Ed25519PrivateKey::try_from(&ed_private_key.to_bytes()[..]).unwrap()], + threshold: 1u8, + } + } +} + +impl PrivateKey for MultiEd25519PrivateKey { + type PublicKeyMaterial = MultiEd25519PublicKey; +} + +impl SigningKey for MultiEd25519PrivateKey { + type SignatureMaterial = MultiEd25519Signature; + type VerifyingKeyMaterial = MultiEd25519PublicKey; + + fn sign(&self, message: &T) -> MultiEd25519Signature { + let mut bitmap = [0u8; BITMAP_NUM_OF_BYTES]; + let signatures: Vec = self + .private_keys + .iter() + .take(self.threshold as usize) + .enumerate() + .map(|(i, item)| { + bitmap_set_bit(&mut bitmap, i); + item.sign(message) + }) + .collect(); + + MultiEd25519Signature { signatures, bitmap } + } + + #[cfg(any(test, feature = "fuzzing"))] + fn sign_arbitrary_message(&self, message: &[u8]) -> MultiEd25519Signature { + let mut signatures: Vec = Vec::with_capacity(self.threshold as usize); + let mut bitmap = [0u8; BITMAP_NUM_OF_BYTES]; + signatures.extend( + self.private_keys + .iter() + .take(self.threshold as usize) + .enumerate() + .map(|(i, item)| { + bitmap_set_bit(&mut bitmap, i); + item.sign_arbitrary_message(message) + }), + ); + MultiEd25519Signature { signatures, bitmap } + } +} + +// Generating a random K out-of N key for testing. +impl Uniform for MultiEd25519PrivateKey { + fn generate(rng: &mut R) -> Self + where + R: ::rand::RngCore + ::rand::CryptoRng, + { + let num_of_keys = rng.gen_range(1..=MAX_NUM_OF_KEYS); + let mut private_keys: Vec = Vec::with_capacity(num_of_keys); + for _ in 0..num_of_keys { + private_keys.push( + Ed25519PrivateKey::try_from( + &ed25519_dalek::SecretKey::generate(rng).to_bytes()[..], + ) + .unwrap(), + ); + } + let threshold = rng.gen_range(1..=num_of_keys) as u8; + MultiEd25519PrivateKey { + private_keys, + threshold, + } + } +} + +impl TryFrom<&[u8]> for MultiEd25519PrivateKey { + type Error = CryptoMaterialError; + + /// Deserialize an Ed25519PrivateKey. This method will also check for key and threshold validity. + fn try_from(bytes: &[u8]) -> std::result::Result { + if bytes.is_empty() { + return Err(CryptoMaterialError::WrongLengthError); + } + let threshold = check_and_get_threshold(bytes, ED25519_PRIVATE_KEY_LENGTH)?; + + let private_keys: Result, _> = bytes + .chunks_exact(ED25519_PRIVATE_KEY_LENGTH) + .map(Ed25519PrivateKey::try_from) + .collect(); + + private_keys.map(|private_keys| MultiEd25519PrivateKey { + private_keys, + threshold, + }) + } +} + +impl Length for MultiEd25519PrivateKey { + fn length(&self) -> usize { + self.private_keys.len() * ED25519_PRIVATE_KEY_LENGTH + 1 + } +} + +impl ValidCryptoMaterial for MultiEd25519PrivateKey { + fn to_bytes(&self) -> Vec { + self.to_bytes() + } +} + +impl Genesis for MultiEd25519PrivateKey { + fn genesis() -> Self { + let mut buf = [0u8; ED25519_PRIVATE_KEY_LENGTH]; + buf[ED25519_PRIVATE_KEY_LENGTH - 1] = 1u8; + MultiEd25519PrivateKey { + private_keys: vec![Ed25519PrivateKey::try_from(buf.as_ref()).unwrap()], + threshold: 1u8, + } + } +} + +////////////////////// +// PublicKey Traits // +////////////////////// + +/// Convenient method to create a MultiEd25519PublicKey from a single Ed25519PublicKey. +impl From for MultiEd25519PublicKey { + fn from(ed_public_key: Ed25519PublicKey) -> Self { + MultiEd25519PublicKey { + public_keys: vec![ed_public_key], + threshold: 1u8, + } + } +} + +/// Implementing From<&PrivateKey<...>> allows to derive a public key in a more elegant fashion. +impl From<&MultiEd25519PrivateKey> for MultiEd25519PublicKey { + fn from(private_key: &MultiEd25519PrivateKey) -> Self { + let public_keys = private_key + .private_keys + .iter() + .map(PrivateKey::public_key) + .collect(); + MultiEd25519PublicKey { + public_keys, + threshold: private_key.threshold, + } + } +} + +/// We deduce PublicKey from this. +impl PublicKey for MultiEd25519PublicKey { + type PrivateKeyMaterial = MultiEd25519PrivateKey; +} + +#[allow(clippy::derive_hash_xor_eq)] +impl std::hash::Hash for MultiEd25519PublicKey { + fn hash(&self, state: &mut H) { + let encoded_pubkey = self.to_bytes(); + state.write(&encoded_pubkey); + } +} + +impl TryFrom<&[u8]> for MultiEd25519PublicKey { + type Error = CryptoMaterialError; + + /// Deserialize a MultiEd25519PublicKey. This method will also check for key and threshold + /// validity, and will only deserialize keys that are safe against small subgroup attacks. + fn try_from(bytes: &[u8]) -> std::result::Result { + if bytes.is_empty() { + return Err(CryptoMaterialError::WrongLengthError); + } + let threshold = check_and_get_threshold(bytes, ED25519_PUBLIC_KEY_LENGTH)?; + let public_keys: Result, _> = bytes + .chunks_exact(ED25519_PUBLIC_KEY_LENGTH) + .map(Ed25519PublicKey::try_from) + .collect(); + public_keys.map(|public_keys| { + let public_key = MultiEd25519PublicKey { + public_keys, + threshold, + }; + add_tag!(&public_key, ValidatedPublicKeyTag); + public_key + }) + } +} + +/// We deduce VerifyingKey from pointing to the signature material +/// we get the ability to do `pubkey.validate(msg, signature)` +impl VerifyingKey for MultiEd25519PublicKey { + type SignatureMaterial = MultiEd25519Signature; + type SigningKeyMaterial = MultiEd25519PrivateKey; +} + +impl fmt::Display for MultiEd25519PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex::encode(self.to_bytes())) + } +} + +impl fmt::Debug for MultiEd25519PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "MultiEd25519PublicKey({})", self) + } +} + +impl Length for MultiEd25519PublicKey { + fn length(&self) -> usize { + self.public_keys.len() * ED25519_PUBLIC_KEY_LENGTH + 1 + } +} + +impl ValidCryptoMaterial for MultiEd25519PublicKey { + fn to_bytes(&self) -> Vec { + self.to_bytes() + } +} + +impl MultiEd25519Signature { + /// This method will also sort signatures based on index. + pub fn new( + signatures: Vec<(Ed25519Signature, u8)>, + ) -> std::result::Result { + let num_of_sigs = signatures.len(); + if num_of_sigs == 0 || num_of_sigs > MAX_NUM_OF_KEYS { + return Err(CryptoMaterialError::ValidationError); + } + + let mut sorted_signatures = signatures; + sorted_signatures.sort_by(|a, b| a.1.cmp(&b.1)); + + let mut bitmap = [0u8; BITMAP_NUM_OF_BYTES]; + + // Check if all indexes are unique and < MAX_NUM_OF_KEYS + let (sigs, indexes): (Vec<_>, Vec<_>) = sorted_signatures.iter().cloned().unzip(); + for i in indexes { + // If an index is out of range. + if i < MAX_NUM_OF_KEYS as u8 { + // if an index has been set already (thus, there is a duplicate). + if bitmap_get_bit(bitmap, i as usize) { + return Err(CryptoMaterialError::BitVecError( + "Duplicate signature index".to_string(), + )); + } else { + bitmap_set_bit(&mut bitmap, i as usize); + } + } else { + return Err(CryptoMaterialError::BitVecError( + "Signature index is out of range".to_string(), + )); + } + } + Ok(MultiEd25519Signature { + signatures: sigs, + bitmap, + }) + } + + /// Creates a new MultiEd25519signature by given signatures and bitmap. + pub fn new_with_signatures_and_bitmap( + signatures: Vec, + bitmap: [u8; BITMAP_NUM_OF_BYTES], + ) -> Self { + Self { signatures, bitmap } + } + + /// Getter signatures. + pub fn signatures(&self) -> &Vec { + &self.signatures + } + + /// Getter bitmap. + pub fn bitmap(&self) -> &[u8; BITMAP_NUM_OF_BYTES] { + &self.bitmap + } + + /// Serialize a MultiEd25519Signature in the form of sig0||sig1||..sigN||bitmap. + pub fn to_bytes(&self) -> Vec { + let mut bytes: Vec = self + .signatures + .iter() + .flat_map(|sig| sig.to_bytes().to_vec()) + .collect(); + bytes.extend(&self.bitmap[..]); + bytes + } +} + +////////////////////// +// Signature Traits // +////////////////////// + +impl TryFrom<&[u8]> for MultiEd25519Signature { + type Error = CryptoMaterialError; + + /// Deserialize a MultiEd25519Signature. This method will also check for malleable signatures + /// and bitmap validity. + fn try_from(bytes: &[u8]) -> std::result::Result { + let length = bytes.len(); + let bitmap_num_of_bytes = length % ED25519_SIGNATURE_LENGTH; + let num_of_sigs = length / ED25519_SIGNATURE_LENGTH; + + if num_of_sigs == 0 + || num_of_sigs > MAX_NUM_OF_KEYS + || bitmap_num_of_bytes != BITMAP_NUM_OF_BYTES + { + return Err(CryptoMaterialError::WrongLengthError); + } + + let bitmap = match bytes[length - BITMAP_NUM_OF_BYTES..].try_into() { + Ok(bitmap) => bitmap, + Err(_) => return Err(CryptoMaterialError::DeserializationError), + }; + if bitmap_count_ones(bitmap) != num_of_sigs as u32 { + return Err(CryptoMaterialError::DeserializationError); + } + + let signatures: Result, _> = bytes + .chunks_exact(ED25519_SIGNATURE_LENGTH) + .map(Ed25519Signature::try_from) + .collect(); + signatures.map(|signatures| MultiEd25519Signature { signatures, bitmap }) + } +} + +impl Length for MultiEd25519Signature { + fn length(&self) -> usize { + self.signatures.len() * ED25519_SIGNATURE_LENGTH + BITMAP_NUM_OF_BYTES + } +} + +#[allow(clippy::derive_hash_xor_eq)] +impl std::hash::Hash for MultiEd25519Signature { + fn hash(&self, state: &mut H) { + let encoded_signature = self.to_bytes(); + state.write(&encoded_signature); + } +} + +impl fmt::Display for MultiEd25519Signature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex::encode(&self.to_bytes()[..])) + } +} + +impl fmt::Debug for MultiEd25519Signature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "MultiEd25519Signature({})", self) + } +} + +impl ValidCryptoMaterial for MultiEd25519Signature { + fn to_bytes(&self) -> Vec { + self.to_bytes() + } +} + +impl Signature for MultiEd25519Signature { + type SigningKeyMaterial = MultiEd25519PrivateKey; + type VerifyingKeyMaterial = MultiEd25519PublicKey; + + fn verify( + &self, + message: &T, + public_key: &MultiEd25519PublicKey, + ) -> Result<()> { + // Public keys should be validated to be safe against small subgroup attacks, etc. + precondition!(has_tag!(public_key, ValidatedPublicKeyTag)); + let mut bytes = ::Hasher::seed().to_vec(); + bcs::serialize_into(&mut bytes, &message) + .map_err(|_| CryptoMaterialError::SerializationError)?; + Self::verify_arbitrary_msg(self, &bytes, public_key) + } + + /// Checks that `self` is valid for an arbitrary &[u8] `message` using `public_key`. + /// Outside of this crate, this particular function should only be used for native signature + /// verification in Move. + fn verify_arbitrary_msg( + &self, + message: &[u8], + public_key: &MultiEd25519PublicKey, + ) -> Result<()> { + // Public keys should be validated to be safe against small subgroup attacks, etc. + precondition!(has_tag!(public_key, ValidatedPublicKeyTag)); + match bitmap_last_set_bit(self.bitmap) { + Some(last_bit) if last_bit as usize <= public_key.length() => (), + _ => { + return Err(anyhow!( + "{}", + CryptoMaterialError::BitVecError("Signature index is out of range".to_string()) + )) + }, + }; + if bitmap_count_ones(self.bitmap) < public_key.threshold as u32 { + return Err(anyhow!( + "{}", + CryptoMaterialError::BitVecError( + "Not enough signatures to meet the threshold".to_string() + ) + )); + } + let mut bitmap_index = 0; + // TODO use deterministic batch verification when gets available. + for sig in &self.signatures { + while !bitmap_get_bit(self.bitmap, bitmap_index) { + bitmap_index += 1; + } + sig.verify_arbitrary_msg(message, &public_key.public_keys[bitmap_index])?; + bitmap_index += 1; + } + Ok(()) + } + + fn to_bytes(&self) -> Vec { + self.to_bytes() + } +} + +impl From for MultiEd25519Signature { + fn from(ed_signature: Ed25519Signature) -> Self { + MultiEd25519Signature { + signatures: vec![ed_signature], + // "1000_0000 0000_0000 0000_0000 0000_0000" + bitmap: [0b1000_0000u8, 0u8, 0u8, 0u8], + } + } +} + +////////////////////// +// Helper functions // +////////////////////// + +// Helper function required to MultiEd25519 keys to_bytes to add the threshold. +fn to_bytes(keys: &[T], threshold: u8) -> Vec { + let mut bytes: Vec = keys + .iter() + .flat_map(ValidCryptoMaterial::to_bytes) + .collect(); + bytes.push(threshold); + bytes +} + +// Helper method to get threshold from a serialized MultiEd25519 key payload. +fn check_and_get_threshold( + bytes: &[u8], + key_size: usize, +) -> std::result::Result { + let payload_length = bytes.len(); + if bytes.is_empty() { + return Err(CryptoMaterialError::WrongLengthError); + } + let threshold_num_of_bytes = payload_length % key_size; + let num_of_keys = payload_length / key_size; + let threshold_byte = bytes[bytes.len() - 1]; + + if num_of_keys == 0 || num_of_keys > MAX_NUM_OF_KEYS || threshold_num_of_bytes != 1 { + Err(CryptoMaterialError::WrongLengthError) + } else if threshold_byte == 0 || threshold_byte > num_of_keys as u8 { + Err(CryptoMaterialError::ValidationError) + } else { + Ok(threshold_byte) + } +} + +fn bitmap_set_bit(input: &mut [u8; BITMAP_NUM_OF_BYTES], index: usize) { + let bucket = index / 8; + // It's always invoked with index < 32, thus there is no need to check range. + let bucket_pos = index - (bucket * 8); + input[bucket] |= 128 >> bucket_pos as u8; +} + +// Helper method to get the input's bit at index. +fn bitmap_get_bit(input: [u8; BITMAP_NUM_OF_BYTES], index: usize) -> bool { + let bucket = index / 8; + // It's always invoked with index < 32, thus there is no need to check range. + let bucket_pos = index - (bucket * 8); + (input[bucket] & (128 >> bucket_pos as u8)) != 0 +} + +// Returns the number of set bits. +fn bitmap_count_ones(input: [u8; BITMAP_NUM_OF_BYTES]) -> u32 { + input.iter().map(|a| a.count_ones()).sum() +} + +// Find the last set bit. +fn bitmap_last_set_bit(input: [u8; BITMAP_NUM_OF_BYTES]) -> Option { + input + .iter() + .rev() + .enumerate() + .find(|(_, byte)| byte != &&0u8) + .map(|(i, byte)| (8 * (BITMAP_NUM_OF_BYTES - i) - byte.trailing_zeros() as usize - 1) as u8) +} + +#[test] +fn bitmap_tests() { + let mut bitmap = [0b0100_0000u8, 0b1111_1111u8, 0u8, 0b1000_0000u8]; + assert!(!bitmap_get_bit(bitmap, 0)); + assert!(bitmap_get_bit(bitmap, 1)); + for i in 8..16 { + assert!(bitmap_get_bit(bitmap, i)); + } + for i in 16..24 { + assert!(!bitmap_get_bit(bitmap, i)); + } + assert!(bitmap_get_bit(bitmap, 24)); + assert!(!bitmap_get_bit(bitmap, 31)); + assert_eq!(bitmap_last_set_bit(bitmap), Some(24)); + + bitmap_set_bit(&mut bitmap, 30); + assert!(bitmap_get_bit(bitmap, 30)); + assert_eq!(bitmap_last_set_bit(bitmap), Some(30)); +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/noise.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/noise.rs new file mode 100644 index 000000000..043e6ac7c --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/noise.rs @@ -0,0 +1,722 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Noise is a [protocol framework](https://noiseprotocol.org/) which we use in Diem to +//! encrypt and authenticate communications between nodes of the network. +//! +//! This file implements a stripped-down version of Noise_IK_25519_AESGCM_SHA256. +//! This means that only the parts that we care about (the IK handshake) are implemented. +//! +//! Note that to benefit from hardware support for AES, you must build this crate with the following +//! flags: `RUSTFLAGS="-Ctarget-cpu=skylake -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3"`. +//! +//! Usage example: +//! +//! ``` +//! use diem_crypto::{noise, x25519, traits::*}; +//! use rand::prelude::*; +//! +//! # fn main() -> Result<(), diem_crypto::noise::NoiseError> { +//! let mut rng = rand::thread_rng(); +//! let initiator_static = x25519::PrivateKey::generate(&mut rng); +//! let responder_static = x25519::PrivateKey::generate(&mut rng); +//! let responder_public = responder_static.public_key(); +//! +//! let initiator = noise::NoiseConfig::new(initiator_static); +//! let responder = noise::NoiseConfig::new(responder_static); +//! +//! let payload1 = b"the client can send an optional payload in the first message"; +//! let mut buffer = vec![0u8; noise::handshake_init_msg_len(payload1.len())]; +//! let initiator_state = initiator +//! .initiate_connection(&mut rng, b"prologue", responder_public, Some(payload1), &mut buffer)?; +//! +//! let payload2 = b"the server can send an optional payload as well as part of the handshake"; +//! let mut buffer2 = vec![0u8; noise::handshake_resp_msg_len(payload2.len())]; +//! let (received_payload, mut responder_session) = responder +//! .respond_to_client_and_finalize(&mut rng, b"prologue", &buffer, Some(payload2), &mut buffer2)?; +//! assert_eq!(received_payload.as_slice(), &payload1[..]); +//! +//! let (received_payload, mut initiator_session) = initiator +//! .finalize_connection(initiator_state, &buffer2)?; +//! assert_eq!(received_payload.as_slice(), &payload2[..]); +//! +//! let message_sent = b"hello world".to_vec(); +//! let mut buffer = message_sent.clone(); +//! let auth_tag = initiator_session +//! .write_message_in_place(&mut buffer)?; +//! buffer.extend_from_slice(&auth_tag); +//! +//! let received_message = responder_session +//! .read_message_in_place(&mut buffer)?; +//! +//! assert_eq!(received_message, message_sent.as_slice()); +//! +//! # Ok(()) +//! # } +//! ``` +//! +#![allow(clippy::integer_arithmetic)] + +use crate::{hash::HashValue, hkdf::Hkdf, traits::Uniform as _, x25519}; +use aes_gcm::{ + aead::{generic_array::GenericArray, Aead, AeadInPlace, NewAead, Payload}, + Aes256Gcm, +}; +use sha2::Digest; +use std::{ + convert::TryFrom as _, + io::{Cursor, Read as _, Write as _}, +}; +use thiserror::Error; + +// +// Useful constants +// ---------------- +// + +/// A noise message cannot be larger than 65535 bytes as per the specification. +pub const MAX_SIZE_NOISE_MSG: usize = 65535; + +/// The authentication tag length of AES-GCM. +pub const AES_GCM_TAGLEN: usize = 16; + +/// The only Noise handshake protocol that we implement in this file. +const PROTOCOL_NAME: &[u8] = b"Noise_IK_25519_AESGCM_SHA256\0\0\0\0"; + +/// The nonce size we use for AES-GCM. +const AES_NONCE_SIZE: usize = 12; + +/// A handy const fn to get the expanded size of a plaintext after encryption +pub const fn encrypted_len(plaintext_len: usize) -> usize { + plaintext_len + AES_GCM_TAGLEN +} + +/// A handy const fn to get the size of a plaintext from a ciphertext size +pub const fn decrypted_len(ciphertext_len: usize) -> usize { + ciphertext_len - AES_GCM_TAGLEN +} + +/// A handy const fn to get the size of the first handshake message +pub const fn handshake_init_msg_len(payload_len: usize) -> usize { + // e + let e_len = x25519::PUBLIC_KEY_SIZE; + // encrypted s + let enc_s_len = encrypted_len(x25519::PUBLIC_KEY_SIZE); + // encrypted payload + let enc_payload_len = encrypted_len(payload_len); + // + e_len + enc_s_len + enc_payload_len +} + +/// A handy const fn to get the size of the second handshake message +pub const fn handshake_resp_msg_len(payload_len: usize) -> usize { + // e + let e_len = x25519::PUBLIC_KEY_SIZE; + // encrypted payload + let enc_payload_len = encrypted_len(payload_len); + // + e_len + enc_payload_len +} + +/// This implementation relies on the fact that the hash function used has a 256-bit output +#[rustfmt::skip] +const _: [(); 32] = [(); HashValue::LENGTH]; + +// +// Errors +// ------ +// + +/// A NoiseError enum represents the different types of error that noise can return to users of the crate +#[derive(Debug, Error)] +pub enum NoiseError { + /// the received message is too short to contain the expected data + #[error("noise: the received message is too short to contain the expected data")] + MsgTooShort, + + /// HKDF has failed (in practice there is no reason for HKDF to fail) + #[error("noise: HKDF has failed")] + Hkdf, + + /// encryption has failed (in practice there is no reason for encryption to fail) + #[error("noise: encryption has failed")] + Encrypt, + + /// could not decrypt the received data (most likely the data was tampered with + #[error("noise: could not decrypt the received data")] + Decrypt, + + /// the public key received is of the wrong format + #[error("noise: the public key received is of the wrong format")] + WrongPublicKeyReceived, + + /// session was closed due to decrypt error + #[error("noise: session was closed due to decrypt error")] + SessionClosed, + + /// the payload that we are trying to send is too large + #[error("noise: the payload that we are trying to send is too large")] + PayloadTooLarge, + + /// the message we received is too large + #[error("noise: the message we received is too large")] + ReceivedMsgTooLarge, + + /// the response buffer passed as argument is too small + #[error("noise: the response buffer passed as argument is too small")] + ResponseBufferTooSmall, + + /// the nonce exceeds the maximum u64 value (in practice this should not happen) + #[error("noise: the nonce exceeds the maximum u64 value")] + NonceOverflow, +} + +// +// helpers +// ------- +// + +fn hash(data: &[u8]) -> Vec { + sha2::Sha256::digest(data).to_vec() +} + +fn hkdf(ck: &[u8], dh_output: Option<&[u8]>) -> Result<(Vec, Vec), NoiseError> { + let dh_output = dh_output.unwrap_or(&[]); + let hkdf_output = if dh_output.is_empty() { + Hkdf::::extract_then_expand_no_ikm(Some(ck), None, 64) + } else { + Hkdf::::extract_then_expand(Some(ck), dh_output, None, 64) + }; + + let hkdf_output = hkdf_output.map_err(|_| NoiseError::Hkdf)?; + let (k1, k2) = hkdf_output.split_at(32); + Ok((k1.to_vec(), k2.to_vec())) +} + +fn mix_hash(h: &mut Vec, data: &[u8]) { + h.extend_from_slice(data); + *h = hash(h); +} + +fn mix_key(ck: &mut Vec, dh_output: &[u8]) -> Result, NoiseError> { + let (new_ck, k) = hkdf(ck, Some(dh_output))?; + *ck = new_ck; + Ok(k) +} + +// +// Noise implementation +// -------------------- +// + +/// A key holder structure used for both initiators and responders. +#[derive(Debug)] +pub struct NoiseConfig { + private_key: x25519::PrivateKey, + public_key: x25519::PublicKey, +} + +/// Refer to the Noise protocol framework specification in order to understand these fields. +#[cfg_attr(test, derive(Clone))] +pub struct InitiatorHandshakeState { + /// rolling hash + h: Vec, + /// chaining key + ck: Vec, + /// ephemeral key + e: x25519::PrivateKey, + /// remote static key used + rs: x25519::PublicKey, +} + +/// Refer to the Noise protocol framework specification in order to understand these fields. +#[cfg_attr(test, derive(Clone))] +pub struct ResponderHandshakeState { + /// rolling hash + h: Vec, + /// chaining key + ck: Vec, + /// remote static key received + rs: x25519::PublicKey, + /// remote ephemeral key receiced + re: x25519::PublicKey, +} + +impl NoiseConfig { + /// A peer must create a NoiseConfig through this function before being able to connect with other peers. + pub fn new(private_key: x25519::PrivateKey) -> Self { + // we could take a public key as argument, and it would be faster, but this is cleaner + let public_key = private_key.public_key(); + Self { + private_key, + public_key, + } + } + + /// Handy getter to access the configuration's public key + pub fn public_key(&self) -> x25519::PublicKey { + self.public_key + } + + // + // Initiator + // --------- + + /// An initiator can use this function to initiate a handshake with a known responder. + pub fn initiate_connection( + &self, + rng: &mut (impl rand::RngCore + rand::CryptoRng), + prologue: &[u8], + remote_public: x25519::PublicKey, + payload: Option<&[u8]>, + response_buffer: &mut [u8], + ) -> Result { + // checks + let payload_len = payload.map(<[u8]>::len).unwrap_or(0); + let buffer_size_required = handshake_init_msg_len(payload_len); + if buffer_size_required > MAX_SIZE_NOISE_MSG { + return Err(NoiseError::PayloadTooLarge); + } + if response_buffer.len() < buffer_size_required { + return Err(NoiseError::ResponseBufferTooSmall); + } + // initialize + let mut h = PROTOCOL_NAME.to_vec(); + let mut ck = PROTOCOL_NAME.to_vec(); + let rs = remote_public; // for naming consistency with the specification + mix_hash(&mut h, prologue); + mix_hash(&mut h, rs.as_slice()); + + // -> e + let e = x25519::PrivateKey::generate(rng); + let e_pub = e.public_key(); + + mix_hash(&mut h, e_pub.as_slice()); + let mut response_buffer = Cursor::new(response_buffer); + response_buffer + .write(e_pub.as_slice()) + .map_err(|_| NoiseError::ResponseBufferTooSmall)?; + + // -> es + let dh_output = e.diffie_hellman(&rs); + let k = mix_key(&mut ck, &dh_output)?; + + // -> s + let aead = Aes256Gcm::new(GenericArray::from_slice(&k)); + + let msg_and_ad = Payload { + msg: self.public_key.as_slice(), + aad: &h, + }; + let nonce = GenericArray::from_slice(&[0u8; AES_NONCE_SIZE]); + let encrypted_static = aead + .encrypt(nonce, msg_and_ad) + .map_err(|_| NoiseError::Encrypt)?; + + mix_hash(&mut h, &encrypted_static); + response_buffer + .write(&encrypted_static) + .map_err(|_| NoiseError::ResponseBufferTooSmall)?; + + // -> ss + let dh_output = self.private_key.diffie_hellman(&rs); + let k = mix_key(&mut ck, &dh_output)?; + + // -> payload + let aead = Aes256Gcm::new(GenericArray::from_slice(&k)); + + let msg_and_ad = Payload { + msg: payload.unwrap_or(&[]), + aad: &h, + }; + let nonce = GenericArray::from_slice(&[0u8; AES_NONCE_SIZE]); + let encrypted_payload = aead + .encrypt(nonce, msg_and_ad) + .map_err(|_| NoiseError::Encrypt)?; + + mix_hash(&mut h, &encrypted_payload); + + response_buffer + .write(&encrypted_payload) + .map_err(|_| NoiseError::ResponseBufferTooSmall)?; + + // return + let handshake_state = InitiatorHandshakeState { h, ck, e, rs }; + Ok(handshake_state) + } + + /// A client can call this to finalize a connection, after receiving an answer from a server. + pub fn finalize_connection( + &self, + handshake_state: InitiatorHandshakeState, + received_message: &[u8], + ) -> Result<(Vec, NoiseSession), NoiseError> { + // checks + if received_message.len() > MAX_SIZE_NOISE_MSG { + return Err(NoiseError::ReceivedMsgTooLarge); + } + // retrieve handshake state + let InitiatorHandshakeState { + mut h, + mut ck, + e, + rs, + } = handshake_state; + + // <- e + let mut re = [0u8; x25519::PUBLIC_KEY_SIZE]; + let mut cursor = Cursor::new(received_message); + cursor + .read_exact(&mut re) + .map_err(|_| NoiseError::MsgTooShort)?; + mix_hash(&mut h, &re); + let re = x25519::PublicKey::from(re); + + // <- ee + let dh_output = e.diffie_hellman(&re); + mix_key(&mut ck, &dh_output)?; + + // <- se + let dh_output = self.private_key.diffie_hellman(&re); + let k = mix_key(&mut ck, &dh_output)?; + + // <- payload + let offset = cursor.position() as usize; + let received_encrypted_payload = &cursor.into_inner()[offset..]; + + let aead = Aes256Gcm::new(GenericArray::from_slice(&k)); + + let nonce = GenericArray::from_slice(&[0u8; AES_NONCE_SIZE]); + let ct_and_ad = Payload { + msg: received_encrypted_payload, + aad: &h, + }; + let received_payload = aead + .decrypt(nonce, ct_and_ad) + .map_err(|_| NoiseError::Decrypt)?; + + // split + let (k1, k2) = hkdf(&ck, None)?; + let session = NoiseSession::new(k1, k2, rs); + + // + Ok((received_payload, session)) + } + + // + // Responder + // --------- + // There are two ways to use this API: + // - either use `parse_client_init_message()` followed by `respond_to_client()` + // - or use the all-in-one `respond_to_client_and_finalize()` + // + // the reason for the first deconstructed API is that we might want to do + // some validation of the received initiator's public key which might + // + + /// A responder can accept a connection by first parsing an initiator message. + /// The function respond_to_client is usually called after this to respond to the initiator. + pub fn parse_client_init_message( + &self, + prologue: &[u8], + received_message: &[u8], + ) -> Result< + ( + x25519::PublicKey, // initiator's public key + ResponderHandshakeState, // state to be used in respond_to_client + Vec, // payload received + ), + NoiseError, + > { + // checks + if received_message.len() > MAX_SIZE_NOISE_MSG { + return Err(NoiseError::ReceivedMsgTooLarge); + } + // initialize + let mut h = PROTOCOL_NAME.to_vec(); + let mut ck = PROTOCOL_NAME.to_vec(); + mix_hash(&mut h, prologue); + mix_hash(&mut h, self.public_key.as_slice()); + + // buffer message received + let mut cursor = Cursor::new(received_message); + + // <- e + let mut re = [0u8; x25519::PUBLIC_KEY_SIZE]; + cursor + .read_exact(&mut re) + .map_err(|_| NoiseError::MsgTooShort)?; + mix_hash(&mut h, &re); + let re = x25519::PublicKey::from(re); + + // <- es + let dh_output = self.private_key.diffie_hellman(&re); + let k = mix_key(&mut ck, &dh_output)?; + + // <- s + let mut encrypted_remote_static = [0u8; x25519::PUBLIC_KEY_SIZE + AES_GCM_TAGLEN]; + cursor + .read_exact(&mut encrypted_remote_static) + .map_err(|_| NoiseError::MsgTooShort)?; + + let aead = Aes256Gcm::new(GenericArray::from_slice(&k)); + + let nonce = GenericArray::from_slice(&[0u8; AES_NONCE_SIZE]); + let ct_and_ad = Payload { + msg: &encrypted_remote_static, + aad: &h, + }; + let rs = aead + .decrypt(nonce, ct_and_ad) + .map_err(|_| NoiseError::Decrypt)?; + let rs = x25519::PublicKey::try_from(rs.as_slice()) + .map_err(|_| NoiseError::WrongPublicKeyReceived)?; + mix_hash(&mut h, &encrypted_remote_static); + + // <- ss + let dh_output = self.private_key.diffie_hellman(&rs); + let k = mix_key(&mut ck, &dh_output)?; + + // <- payload + let offset = cursor.position() as usize; + let received_encrypted_payload = &cursor.into_inner()[offset..]; + + let aead = Aes256Gcm::new(GenericArray::from_slice(&k)); + + let nonce = GenericArray::from_slice(&[0u8; AES_NONCE_SIZE]); + let ct_and_ad = Payload { + msg: received_encrypted_payload, + aad: &h, + }; + let received_payload = aead + .decrypt(nonce, ct_and_ad) + .map_err(|_| NoiseError::Decrypt)?; + mix_hash(&mut h, received_encrypted_payload); + + // return + let handshake_state = ResponderHandshakeState { h, ck, rs, re }; + Ok((rs, handshake_state, received_payload)) + } + + /// A responder can respond to an initiator by calling this function with the state obtained, + /// after calling parse_client_init_message + pub fn respond_to_client( + &self, + rng: &mut (impl rand::RngCore + rand::CryptoRng), + handshake_state: ResponderHandshakeState, + payload: Option<&[u8]>, + response_buffer: &mut [u8], + ) -> Result { + // checks + let payload_len = payload.map(<[u8]>::len).unwrap_or(0); + let buffer_size_required = handshake_resp_msg_len(payload_len); + if buffer_size_required > MAX_SIZE_NOISE_MSG { + return Err(NoiseError::PayloadTooLarge); + } + if response_buffer.len() < buffer_size_required { + return Err(NoiseError::ResponseBufferTooSmall); + } + + // retrieve handshake state + let ResponderHandshakeState { + mut h, + mut ck, + rs, + re, + } = handshake_state; + + // -> e + let e = x25519::PrivateKey::generate(rng); + let e_pub = e.public_key(); + + mix_hash(&mut h, e_pub.as_slice()); + let mut response_buffer = Cursor::new(response_buffer); + response_buffer + .write(e_pub.as_slice()) + .map_err(|_| NoiseError::ResponseBufferTooSmall)?; + + // -> ee + let dh_output = e.diffie_hellman(&re); + mix_key(&mut ck, &dh_output)?; + + // -> se + let dh_output = e.diffie_hellman(&rs); + let k = mix_key(&mut ck, &dh_output)?; + + // -> payload + let aead = Aes256Gcm::new(GenericArray::from_slice(&k)); + + let msg_and_ad = Payload { + msg: payload.unwrap_or(&[]), + aad: &h, + }; + let nonce = GenericArray::from_slice(&[0u8; AES_NONCE_SIZE]); + let encrypted_payload = aead + .encrypt(nonce, msg_and_ad) + .map_err(|_| NoiseError::Encrypt)?; + mix_hash(&mut h, &encrypted_payload); + response_buffer + .write(&encrypted_payload) + .map_err(|_| NoiseError::ResponseBufferTooSmall)?; + + // split + let (k1, k2) = hkdf(&ck, None)?; + let session = NoiseSession::new(k2, k1, rs); + + // + Ok(session) + } + + /// This function is a one-call that replaces calling the two functions parse_client_init_message + /// and respond_to_client consecutively + pub fn respond_to_client_and_finalize( + &self, + rng: &mut (impl rand::RngCore + rand::CryptoRng), + prologue: &[u8], + received_message: &[u8], + payload: Option<&[u8]>, + response_buffer: &mut [u8], + ) -> Result< + ( + Vec, // the payload the initiator sent + NoiseSession, // The created session + ), + NoiseError, + > { + let (_, handshake_state, received_payload) = + self.parse_client_init_message(prologue, received_message)?; + let session = self.respond_to_client(rng, handshake_state, payload, response_buffer)?; + Ok((received_payload, session)) + } +} + +// +// Post-Handshake +// -------------- + +/// A NoiseSession is produced after a successful Noise handshake, and can be use to encrypt and decrypt messages to the other peer. +#[cfg_attr(test, derive(Clone))] +pub struct NoiseSession { + /// a session can be marked as invalid if it has seen a decryption failure + valid: bool, + /// the public key of the other peer + remote_public_key: x25519::PublicKey, + /// key used to encrypt messages to the other peer + write_key: Vec, + /// associated nonce (in practice the maximum u64 value cannot be reached) + write_nonce: u64, + /// key used to decrypt messages received from the other peer + read_key: Vec, + /// associated nonce (in practice the maximum u64 value cannot be reached) + read_nonce: u64, +} + +impl NoiseSession { + fn new(write_key: Vec, read_key: Vec, remote_public_key: x25519::PublicKey) -> Self { + Self { + valid: true, + remote_public_key, + write_key, + write_nonce: 0, + read_key, + read_nonce: 0, + } + } + + /// create a dummy session with 0 keys + #[cfg(any(test, feature = "fuzzing"))] + pub fn new_for_testing() -> Self { + Self::new( + vec![0u8; 32], + vec![0u8; 32], + [0u8; x25519::PUBLIC_KEY_SIZE].into(), + ) + } + + /// obtain remote static public key + pub fn get_remote_static(&self) -> x25519::PublicKey { + self.remote_public_key + } + + /// encrypts a message for the other peers (post-handshake) + /// the function encrypts in place, and returns the authentication tag as result + pub fn write_message_in_place(&mut self, message: &mut [u8]) -> Result, NoiseError> { + // checks + if !self.valid { + return Err(NoiseError::SessionClosed); + } + if message.len() > MAX_SIZE_NOISE_MSG - AES_GCM_TAGLEN { + return Err(NoiseError::PayloadTooLarge); + } + + // encrypt in place + let aead = Aes256Gcm::new(GenericArray::from_slice(&self.write_key)); + let mut nonce = [0u8; 4].to_vec(); + nonce.extend_from_slice(&self.write_nonce.to_be_bytes()); + let nonce = GenericArray::from_slice(&nonce); + + let authentication_tag = aead + .encrypt_in_place_detached(nonce, b"", message) + .map_err(|_| NoiseError::Encrypt)?; + + // increment nonce + self.write_nonce = self + .write_nonce + .checked_add(1) + .ok_or(NoiseError::NonceOverflow)?; + + // return a subslice without the authentication tag + Ok(authentication_tag.to_vec()) + } + + /// decrypts a message from the other peer (post-handshake) + /// the function decrypts in place, and returns a subslice without the auth tag + pub fn read_message_in_place<'a>( + &mut self, + message: &'a mut [u8], + ) -> Result<&'a [u8], NoiseError> { + // checks + if !self.valid { + return Err(NoiseError::SessionClosed); + } + if message.len() > MAX_SIZE_NOISE_MSG { + self.valid = false; + return Err(NoiseError::ReceivedMsgTooLarge); + } + if message.len() < AES_GCM_TAGLEN { + self.valid = false; + return Err(NoiseError::ResponseBufferTooSmall); + } + + // decrypt in place + let aead = Aes256Gcm::new(GenericArray::from_slice(&self.read_key)); + + let mut nonce = [0u8; 4].to_vec(); + nonce.extend_from_slice(&self.read_nonce.to_be_bytes()); + let nonce = GenericArray::from_slice(&nonce); + + let (buffer, authentication_tag) = message.split_at_mut(message.len() - AES_GCM_TAGLEN); + let authentication_tag = GenericArray::from_slice(authentication_tag); + aead.decrypt_in_place_detached(nonce, b"", buffer, authentication_tag) + .map_err(|_| { + self.valid = false; + NoiseError::Decrypt + })?; + + // increment nonce + self.read_nonce = self + .read_nonce + .checked_add(1) + .ok_or(NoiseError::NonceOverflow)?; + + // return a subslice of the buffer representing the decrypted plaintext + Ok(buffer) + } +} + +impl std::fmt::Debug for NoiseSession { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "NoiseSession[...]") + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/tags.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/tags.rs new file mode 100644 index 000000000..9473c6b7a --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/tags.rs @@ -0,0 +1,20 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides definitions of tag types to be used by MIRAI analyzing diem-crypto. +//! This module gets compiled only if the diem-crypto is compiled via MIRAI in a debug build. + +use mirai_annotations::*; + +/// A MIRAI tag type that tracks if a public key is checked to protect against invalid point +/// attacks, small subgroup attacks, and typos. This tag type is only used at compilation time. +/// This type should only be accessible inside diem-crypto. +pub type ValidatedPublicKeyTag = ValidatedPublicKeyTagKind; + +/// A generic tag type intended to only be used by ValidatedPublicKeyTag +pub struct ValidatedPublicKeyTagKind {} + +/// The propagation set of ValidatedPublicKeyTag. An empty propagation set is used to make sure that +/// ValidatedPublicKeyTag can only be explicitly attached to public keys. +const VALIDATED_PUBLIC_KEY_TAG_MASK: TagPropagationSet = tag_propagation_set!(); diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/test_utils.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/test_utils.rs new file mode 100644 index 000000000..ecb936716 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/test_utils.rs @@ -0,0 +1,215 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Internal module containing convenience utility functions mainly for testing + +use crate::traits::Uniform; +use serde::{Deserialize, Serialize}; + +/// A deterministic seed for PRNGs related to keys +pub const TEST_SEED: [u8; 32] = [0u8; 32]; + +/// A keypair consisting of a private and public key +#[cfg_attr(feature = "cloneable-private-keys", derive(Clone))] +#[derive(Serialize, Deserialize, PartialEq, Eq)] +pub struct KeyPair +where + for<'a> P: From<&'a S>, +{ + /// the private key component + pub private_key: S, + /// the public key component + pub public_key: P, +} + +impl From for KeyPair +where + for<'a> P: From<&'a S>, +{ + fn from(private_key: S) -> Self { + KeyPair { + public_key: (&private_key).into(), + private_key, + } + } +} + +impl Uniform for KeyPair +where + S: Uniform, + for<'a> P: From<&'a S>, +{ + fn generate(rng: &mut R) -> Self + where + R: ::rand::RngCore + ::rand::CryptoRng, + { + let private_key = S::generate(rng); + private_key.into() + } +} + +/// A pair consisting of a private and public key +impl Uniform for (S, P) +where + S: Uniform, + for<'a> P: From<&'a S>, +{ + fn generate(rng: &mut R) -> Self + where + R: ::rand::RngCore + ::rand::CryptoRng, + { + let private_key = S::generate(rng); + let public_key = (&private_key).into(); + (private_key, public_key) + } +} + +impl std::fmt::Debug for KeyPair +where + Priv: Serialize, + Pub: Serialize + for<'a> From<&'a Priv>, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut v = bcs::to_bytes(&self.private_key).unwrap(); + v.extend(&bcs::to_bytes(&self.public_key).unwrap()); + write!(f, "{}", hex::encode(&v[..])) + } +} + +#[cfg(any(test, feature = "fuzzing"))] +use proptest::prelude::*; +#[cfg(any(test, feature = "fuzzing"))] +use rand::{rngs::StdRng, SeedableRng}; + +/// Produces a uniformly random keypair from a seed +#[cfg(any(test, feature = "fuzzing"))] +pub fn uniform_keypair_strategy() -> impl Strategy> +where + Pub: Serialize + for<'a> From<&'a Priv>, + Priv: Serialize + Uniform, +{ + // The no_shrink is because keypairs should be fixed -- shrinking would cause a different + // keypair to be generated, which appears to not be very useful. + any::<[u8; 32]>() + .prop_map(|seed| { + let mut rng = StdRng::from_seed(seed); + KeyPair::::generate(&mut rng) + }) + .no_shrink() +} + +/// Produces a uniformly random keypair from a seed and the user can alter this sleed slightly. +/// Useful for circumstances where you want two disjoint keypair generations that may interact with +/// each other. +#[cfg(any(test, feature = "fuzzing"))] +pub fn uniform_keypair_strategy_with_perturbation( + perturbation: u8, +) -> impl Strategy> +where + Pub: Serialize + for<'a> From<&'a Priv>, + Priv: Serialize + Uniform, +{ + // The no_shrink is because keypairs should be fixed -- shrinking would cause a different + // keypair to be generated, which appears to not be very useful. + any::<[u8; 32]>() + .prop_map(move |mut seed| { + for elem in seed.iter_mut() { + *elem = elem.saturating_add(perturbation); + } + let mut rng = StdRng::from_seed(seed); + KeyPair::::generate(&mut rng) + }) + .no_shrink() +} + +/// This struct provides a means of testing signing and verification through +/// BCS serialization and domain separation +#[cfg(any(test, feature = "fuzzing"))] +#[derive(Debug, Serialize, Deserialize)] +pub struct TestDiemCrypto(pub String); + +// the following block is macro expanded from derive(CryptoHasher, BCSCryptoHash) + +/// Cryptographic hasher for an BCS-serializable #item +#[cfg(any(test, feature = "fuzzing"))] +pub struct TestDiemCryptoHasher(crate::hash::DefaultHasher); +#[cfg(any(test, feature = "fuzzing"))] +impl ::core::clone::Clone for TestDiemCryptoHasher { + #[inline] + fn clone(&self) -> TestDiemCryptoHasher { + match *self { + TestDiemCryptoHasher(ref __self_0_0) => { + TestDiemCryptoHasher(::core::clone::Clone::clone(__self_0_0)) + }, + } + } +} +#[cfg(any(test, feature = "fuzzing"))] +static TEST_DIEM_CRYPTO_SEED: crate::_once_cell::sync::OnceCell<[u8; 32]> = + crate::_once_cell::sync::OnceCell::new(); +#[cfg(any(test, feature = "fuzzing"))] +impl TestDiemCryptoHasher { + fn new() -> Self { + let name = crate::_serde_name::trace_name::() + .expect("The `CryptoHasher` macro only applies to structs and enums"); + TestDiemCryptoHasher(crate::hash::DefaultHasher::new(name.as_bytes())) + } +} +#[cfg(any(test, feature = "fuzzing"))] +static TEST_DIEM_CRYPTO_HASHER: crate::_once_cell::sync::Lazy = + crate::_once_cell::sync::Lazy::new(TestDiemCryptoHasher::new); +#[cfg(any(test, feature = "fuzzing"))] +impl std::default::Default for TestDiemCryptoHasher { + fn default() -> Self { + TEST_DIEM_CRYPTO_HASHER.clone() + } +} +#[cfg(any(test, feature = "fuzzing"))] +impl crate::hash::CryptoHasher for TestDiemCryptoHasher { + fn seed() -> &'static [u8; 32] { + TEST_DIEM_CRYPTO_SEED.get_or_init(|| { + let name = crate::_serde_name::trace_name::() + .expect("The `CryptoHasher` macro only applies to structs and enums.") + .as_bytes(); + crate::hash::DefaultHasher::prefixed_hash(name) + }) + } + + fn update(&mut self, bytes: &[u8]) { + self.0.update(bytes); + } + + fn finish(self) -> crate::hash::HashValue { + self.0.finish() + } +} +#[cfg(any(test, feature = "fuzzing"))] +impl std::io::Write for TestDiemCryptoHasher { + fn write(&mut self, bytes: &[u8]) -> std::io::Result { + self.0.update(bytes); + Ok(bytes.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} +#[cfg(any(test, feature = "fuzzing"))] +impl crate::hash::CryptoHash for TestDiemCrypto { + type Hasher = TestDiemCryptoHasher; + + fn hash(&self) -> crate::hash::HashValue { + use crate::hash::CryptoHasher; + let mut state = Self::Hasher::default(); + bcs::serialize_into(&mut state, &self) + .expect("BCS serialization of TestDiemCrypto should not fail"); + state.finish() + } +} + +/// Produces a random TestDiemCrypto signable / verifiable struct. +#[cfg(any(test, feature = "fuzzing"))] +pub fn random_serializable_struct() -> impl Strategy { + (String::arbitrary()).prop_map(TestDiemCrypto).no_shrink() +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/traits.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/traits.rs new file mode 100644 index 000000000..22d905757 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/traits.rs @@ -0,0 +1,311 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides a generic set of traits for dealing with cryptographic primitives. +//! +//! For examples on how to use these traits, see the implementations of the [`ed25519`] or +//! [`bls12381`] modules. + +use crate::hash::{CryptoHash, CryptoHasher}; +use anyhow::Result; +use core::convert::{From, TryFrom}; +use rand::{rngs::StdRng, CryptoRng, RngCore, SeedableRng}; +use serde::{de::DeserializeOwned, Serialize}; +use std::{fmt::Debug, hash::Hash}; +use thiserror::Error; + +/// An error type for key and signature validation issues, see [`ValidCryptoMaterial`][ValidCryptoMaterial]. +/// +/// This enum reflects there are two interesting causes of validation +/// failure for the ingestion of key or signature material: deserialization errors +/// (often, due to mangled material or curve equation failure for ECC) and +/// validation errors (material recognizable but unacceptable for use, +/// e.g. unsafe). +#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[error("{:?}", self)] +pub enum CryptoMaterialError { + /// Struct to be signed does not serialize correctly. + SerializationError, + /// Key or signature material does not deserialize correctly. + DeserializationError, + /// Key or signature material deserializes, but is otherwise not valid. + ValidationError, + /// Key, threshold or signature material does not have the expected size. + WrongLengthError, + /// Part of the signature or key is not canonical resulting to malleability issues. + CanonicalRepresentationError, + /// A curve point (i.e., a public key) lies on a small group. + SmallSubgroupError, + /// A curve point (i.e., a public key) does not satisfy the curve equation. + PointNotOnCurveError, + /// BitVec errors in accountable multi-sig schemes. + BitVecError(String), +} + +/// The serialized length of the data that enables macro derived serialization and deserialization. +pub trait Length { + /// The serialized length of the data + fn length(&self) -> usize; +} + +/// Key or more generally crypto material with a notion of byte validation. +/// +/// A type family for material that knows how to serialize and +/// deserialize, as well as validate byte-encoded material. The +/// validation must be implemented as a [`TryFrom`][TryFrom] which +/// classifies its failures against the above +/// [`CryptoMaterialError`][CryptoMaterialError]. +/// +/// This provides an implementation for a validation that relies on a +/// round-trip to bytes and corresponding [`TryFrom`][TryFrom]. +pub trait ValidCryptoMaterial: + // The for<'a> exactly matches the assumption "deserializable from any lifetime". + for<'a> TryFrom<&'a [u8], Error = CryptoMaterialError> + Serialize + DeserializeOwned +{ + /// Convert the valid crypto material to bytes. + fn to_bytes(&self) -> Vec; +} + +/// An extension to to/from Strings for [`ValidCryptoMaterial`][ValidCryptoMaterial]. +/// +/// Relies on [`hex`][::hex] for string encoding / decoding. +/// No required fields, provides a default implementation. +pub trait ValidCryptoMaterialStringExt: ValidCryptoMaterial { + /// When trying to convert from bytes, we simply decode the string into + /// bytes before checking if we can convert. + fn from_encoded_string(encoded_str: &str) -> std::result::Result { + let bytes_out = ::hex::decode(encoded_str); + // We defer to `try_from` to make sure we only produce valid crypto materials. + bytes_out + // We reinterpret a failure to serialize: key is mangled someway. + .or(Err(CryptoMaterialError::DeserializationError)) + .and_then(|ref bytes| Self::try_from(bytes)) + } + /// A function to encode into hex-string after serializing. + fn to_encoded_string(&self) -> Result { + Ok(::hex::encode(self.to_bytes())) + } +} + +// There's nothing required in this extension, so let's just derive it +// for anybody that has a ValidCryptoMaterial. +impl ValidCryptoMaterialStringExt for T {} + +/// A type family for key material that should remain secret and has an +/// associated type of the [`PublicKey`][PublicKey] family. +pub trait PrivateKey: Sized { + /// We require public / private types to be coupled, i.e. their + /// associated type is each other. + type PublicKeyMaterial: PublicKey; + + /// Returns the associated public key + fn public_key(&self) -> Self::PublicKeyMaterial { + self.into() + } +} + +/// A type family of valid keys that know how to sign. +/// +/// This trait has a requirement on a `pub(crate)` marker trait meant to +/// specifically limit its implementations to the present crate. +/// +/// A trait for a [`ValidCryptoMaterial`][ValidCryptoMaterial] which knows how to sign a +/// message, and return an associated `Signature` type. +pub trait SigningKey: + PrivateKey::VerifyingKeyMaterial> + + ValidCryptoMaterial + + private::Sealed +{ + /// The associated verifying key type for this signing key. + type VerifyingKeyMaterial: VerifyingKey; + /// The associated signature type for this signing key. + type SignatureMaterial: Signature; + + /// Signs an object that has an distinct domain-separation hasher and + /// that we know how to serialize. There is no pre-hashing into a + /// `HashValue` to be done by the caller. + /// + /// Note: this assumes serialization is unfaillible. See diem_common::bcs::ser + /// for a discussion of this assumption. + fn sign(&self, message: &T) -> Self::SignatureMaterial; + + /// Signs a non-hash input message. For testing only. + #[cfg(any(test, feature = "fuzzing"))] + fn sign_arbitrary_message(&self, message: &[u8]) -> Self::SignatureMaterial; + + /// Returns the associated verifying key + fn verifying_key(&self) -> Self::VerifyingKeyMaterial { + self.public_key() + } +} + +/// Returns the signing message for the given message. +/// It is used by `SigningKey#sign` function. +pub fn signing_message(message: &T) -> Vec { + let mut bytes = ::seed().to_vec(); + bcs::serialize_into(&mut bytes, &message) + .map_err(|_| CryptoMaterialError::SerializationError) + .expect("Serialization of signable material should not fail."); + bytes +} + +/// A type for key material that can be publicly shared, and in asymmetric +/// fashion, can be obtained from a [`PrivateKey`][PrivateKey] +/// reference. +/// This convertibility requirement ensures the existence of a +/// deterministic, canonical public key construction from a private key. +pub trait PublicKey: Sized + Clone + Eq + Hash + + // This unsightly turbofish type parameter is the precise constraint + // needed to require that there exists an + // + // ``` + // impl From<&MyPrivateKeyMaterial> for MyPublicKeyMaterial + // ``` + // + // declaration, for any `MyPrivateKeyMaterial`, `MyPublicKeyMaterial` + // on which we register (respectively) `PublicKey` and `PrivateKey` + // implementations. + for<'a> From<&'a ::PrivateKeyMaterial> { + /// We require public / private types to be coupled, i.e. their + /// associated type is each other. + type PrivateKeyMaterial: PrivateKey; +} + +/// A type family of public keys that are used for signing. +/// +/// This trait has a requirement on a `pub(crate)` marker trait meant to +/// specifically limit its implementations to the present crate. +/// +/// It is linked to a type of the Signature family, which carries the +/// verification implementation. +pub trait VerifyingKey: + PublicKey::SigningKeyMaterial> + + ValidCryptoMaterial + + private::Sealed +{ + /// The associated signing key type for this verifying key. + type SigningKeyMaterial: SigningKey; + /// The associated signature type for this verifying key. + type SignatureMaterial: Signature; + + /// We provide the striaghtfoward implementation which dispatches to the signature. + fn verify_struct_signature( + &self, + message: &T, + signature: &Self::SignatureMaterial, + ) -> Result<()> { + signature.verify(message, self) + } + + /// We provide the implementation which dispatches to the signature. + fn batch_verify( + message: &T, + keys_and_signatures: Vec<(Self, Self::SignatureMaterial)>, + ) -> Result<()> { + Self::SignatureMaterial::batch_verify(message, keys_and_signatures) + } +} + +/// A type family for signature material that knows which public key type +/// is needed to verify it, and given such a public key, knows how to +/// verify. +/// +/// This trait simply requires an association to some type of the +/// [`PublicKey`][PublicKey] family of which we are the `SignatureMaterial`. +/// +/// This trait has a requirement on a `pub(crate)` marker trait meant to +/// specifically limit its implementations to the present crate. +/// +/// It should be possible to write a generic signature function that +/// checks signature material passed as `&[u8]` and only returns Ok when +/// that material de-serializes to a signature of the expected concrete +/// scheme. This would be done as an extension trait of +/// [`Signature`][Signature]. +pub trait Signature: + for<'a> TryFrom<&'a [u8], Error = CryptoMaterialError> + + Sized + + Debug + + Clone + + Eq + + Hash + + private::Sealed +{ + /// The associated verifying key type for this signature. + type VerifyingKeyMaterial: VerifyingKey; + /// The associated signing key type for this signature + type SigningKeyMaterial: SigningKey; + + /// Verification for a struct we unabmiguously know how to serialize and + /// that we have a domain separation prefix for. + fn verify( + &self, + message: &T, + public_key: &Self::VerifyingKeyMaterial, + ) -> Result<()>; + + /// Native verification function. + fn verify_arbitrary_msg( + &self, + message: &[u8], + public_key: &Self::VerifyingKeyMaterial, + ) -> Result<()>; + + /// Convert the signature into a byte representation. + fn to_bytes(&self) -> Vec; + + /// The implementer can override a batch verification implementation + /// that by default iterates over each signature. More efficient + /// implementations exist and should be implemented for many schemes. + fn batch_verify( + message: &T, + keys_and_signatures: Vec<(Self::VerifyingKeyMaterial, Self)>, + ) -> Result<()> { + for (key, signature) in keys_and_signatures { + signature.verify(message, &key)? + } + Ok(()) + } +} + +/// A type family for schemes which know how to generate key material from +/// a cryptographically-secure [`CryptoRng`][::rand::CryptoRng]. +pub trait Uniform { + /// Generate key material from an RNG. This should generally not be used for production + /// purposes even with a good source of randomness. When possible use hardware crypto to generate and + /// store private keys. + fn generate(rng: &mut R) -> Self + where + R: RngCore + CryptoRng; + + /// Generate a random key using the shared TEST_SEED + fn generate_for_testing() -> Self + where + Self: Sized, + { + let mut rng: StdRng = SeedableRng::from_seed(crate::test_utils::TEST_SEED); + Self::generate(&mut rng) + } +} + +/// A type family with a by-convention notion of genesis private key. +pub trait Genesis: PrivateKey { + /// Produces the genesis private key. + fn genesis() -> Self; +} + +/// A pub(crate) mod hiding a Sealed trait and its implementations, allowing +/// us to make sure implementations are constrained to the crypto crate. +// See https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +pub(crate) mod private { + pub trait Sealed {} + + // Implement for the ed25519, multi-ed25519 signatures + impl Sealed for crate::ed25519::Ed25519PrivateKey {} + impl Sealed for crate::ed25519::Ed25519PublicKey {} + impl Sealed for crate::ed25519::Ed25519Signature {} + + impl Sealed for crate::multi_ed25519::MultiEd25519PrivateKey {} + impl Sealed for crate::multi_ed25519::MultiEd25519PublicKey {} + impl Sealed for crate::multi_ed25519::MultiEd25519Signature {} +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/bcs_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/bcs_test.rs new file mode 100644 index 000000000..fe6e78bfb --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/bcs_test.rs @@ -0,0 +1,112 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + ed25519::{ + Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature, ED25519_PRIVATE_KEY_LENGTH, + ED25519_PUBLIC_KEY_LENGTH, ED25519_SIGNATURE_LENGTH, + }, + multi_ed25519::{MultiEd25519PrivateKey, MultiEd25519PublicKey, MultiEd25519Signature}, + test_utils::{TestDiemCrypto, TEST_SEED}, + Signature, SigningKey, Uniform, +}; +use rand::{rngs::StdRng, SeedableRng}; +use std::convert::TryFrom; + +#[test] +fn ed25519_bcs_material() { + use std::borrow::Cow; + + let private_key = + Ed25519PrivateKey::try_from([1u8; ED25519_PRIVATE_KEY_LENGTH].as_ref()).unwrap(); + let public_key = Ed25519PublicKey::from(&private_key); + + let serialized_public_key = bcs::to_bytes(&Cow::Borrowed(&public_key)).unwrap(); + // Expected size should be 1 byte due to BCS length prefix + 32 bytes for the raw key bytes + assert_eq!(serialized_public_key.len(), 1 + ED25519_PUBLIC_KEY_LENGTH); + + // Ensure public key serialization - deserialization is stable and deterministic + let deserialized_public_key: Ed25519PublicKey = + bcs::from_bytes(&serialized_public_key).unwrap(); + assert_eq!(deserialized_public_key, public_key); + + let message = TestDiemCrypto("Hello, World".to_string()); + let signature: Ed25519Signature = private_key.sign(&message); + + let serialized_signature = bcs::to_bytes(&Cow::Borrowed(&signature)).unwrap(); + // Expected size should be 1 byte due to BCS length prefix + 64 bytes for the raw signature bytes + assert_eq!(serialized_signature.len(), 1 + ED25519_SIGNATURE_LENGTH); + + // Ensure signature serialization - deserialization is stable and deterministic + let deserialized_signature: Ed25519Signature = bcs::from_bytes(&serialized_signature).unwrap(); + assert_eq!(deserialized_signature, signature); + + // Verify signature + let verified_signature = signature.verify(&message, &public_key); + assert!(verified_signature.is_ok()) +} + +#[test] +fn multi_ed25519_bcs_material() { + use std::borrow::Cow; + + // Helper function to generate N ed25519 private keys. + fn generate_keys(n: usize) -> Vec { + let mut rng = StdRng::from_seed(TEST_SEED); + (0..n) + .map(|_| Ed25519PrivateKey::generate(&mut rng)) + .collect() + } + + let num_of_keys = 10; + let threshold = 7; + let private_keys_10 = generate_keys(num_of_keys); + let multi_private_key_7of10 = MultiEd25519PrivateKey::new(private_keys_10, threshold).unwrap(); + let multi_public_key_7of10 = MultiEd25519PublicKey::from(&multi_private_key_7of10); + + let serialized_multi_public_key = + bcs::to_bytes(&Cow::Borrowed(&multi_public_key_7of10)).unwrap(); + + // Expected size due to specialization is + // 2 bytes for BCS length prefix (due to ULEB128) + // + 10 * single_pub_key_size bytes (each key is the compressed Edwards Y coordinate) + // + 1 byte for the threshold + assert_eq!( + serialized_multi_public_key.len(), + 2 + num_of_keys * ED25519_PUBLIC_KEY_LENGTH + 1 + ); + + let deserialized_multi_public_key: MultiEd25519PublicKey = + bcs::from_bytes(&serialized_multi_public_key).unwrap(); + assert_eq!(deserialized_multi_public_key, multi_public_key_7of10); + + let message = TestDiemCrypto("Hello, World".to_string()); + + // Verifying a 7-of-10 signature against a public key with the same threshold should pass. + let multi_signature_7of10: MultiEd25519Signature = multi_private_key_7of10.sign(&message); + + let serialized_multi_signature = bcs::to_bytes(&Cow::Borrowed(&multi_signature_7of10)).unwrap(); + // Expected size due to specialization is + // 2 bytes for BCS length prefix (due to ULEB128) + // + 7 * single_signature_size bytes (each sig is of the form (R,s), + // a 32B compressed Edwards Y coordinate concatenated with a 32B scalar) + // + 4 bytes for the bitmap (the bitmap can hold up to 32 bits) + assert_eq!( + serialized_multi_signature.len(), + 2 + threshold as usize * ED25519_SIGNATURE_LENGTH + 4 + ); + + // Verify bitmap + assert_eq!(multi_signature_7of10.bitmap(), &[ + 0b1111_1110, + 0u8, + 0u8, + 0u8 + ]); + + // Verify signature + assert!(multi_signature_7of10 + .verify(&message, &multi_public_key_7of10) + .is_ok()); +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compat_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compat_test.rs new file mode 100644 index 000000000..c76350515 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compat_test.rs @@ -0,0 +1,61 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::compat; +use digest::Digest; +use proptest::{collection::vec, prelude::*}; + +// sanity check our compatibility layer by testing some basic SHA3-256 test vectors. +#[test] +fn check_basic_sha3_256_test_vectors() { + let one_million_a = vec![b'a'; 1_000_000]; + + let tests: [(&[u8], &[u8]); 4] = [ + ( + b"", + b"a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", + ), + ( + b"abc", + b"3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", + ), + ( + b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + b"41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376", + ), + ( + &one_million_a, + b"5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1", + ), + ]; + + for (input, expected_output) in &tests { + let expected_output = hex::decode(expected_output).unwrap(); + let output1 = compat::Sha3_256::digest(input); + let output2 = sha3::Sha3_256::digest(input); + assert_eq!(&expected_output, &output1.as_slice()); + assert_eq!(&expected_output, &output2.as_slice()); + } +} + +proptest! { + // check that RustCrypto SHA3-256 and our compatibility wrapper over tiny-keccak + // SHA3-256 have the exact same behaviour for random inputs. + #[test] + fn sha3_256_compatibility_test( + updates in vec(vec(any::(), 0..200), 0..10) + ) { + let mut hasher1 = compat::Sha3_256::default(); + let mut hasher2 = sha3::Sha3_256::default(); + + for update in updates { + hasher1.update(&update); + hasher2.update(&update); + + let out1 = hasher1.clone().finalize(); + let out2 = hasher2.clone().finalize(); + assert_eq!(&out1, &out2); + } + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test.rs new file mode 100644 index 000000000..3a5567990 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test.rs @@ -0,0 +1,30 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use diem_crypto::{ + ed25519::{Ed25519PrivateKey, Ed25519PublicKey}, + multi_ed25519::{MultiEd25519PrivateKey, MultiEd25519PublicKey}, + test_utils::KeyPair, + traits::*, +}; +use diem_crypto_derive::{CryptoHasher, BCSCryptoHash}; +use rand::{prelude::ThreadRng, thread_rng}; +use serde::{Deserialize, Serialize}; + +#[derive(CryptoHasher, BCSCryptoHash, Serialize, Deserialize)] +struct TestTypedSemantics(String); + +fn main() { + let mut csprng: ThreadRng = thread_rng(); + let ed25519_keypair: KeyPair = + KeyPair::generate(&mut csprng); + + let message = TestTypedSemantics(String::from("hello_world")); + let signature = ed25519_keypair.private_key.sign(&message); + + let multi_ed25519_keypair: KeyPair = + KeyPair::generate(&mut csprng); + + signature.verify(&message, &multi_ed25519_keypair.public_key); +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj.rs new file mode 100644 index 000000000..df3495613 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj.rs @@ -0,0 +1,9 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use diem_crypto::traits::*; + +fn main() { + let mut l: Vec> = vec![]; +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj_pub.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj_pub.rs new file mode 100644 index 000000000..a00eeea14 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj_pub.rs @@ -0,0 +1,9 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use diem_crypto::traits::*; + +fn main() { + let mut l: Vec> = vec![]; +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj_sig.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj_sig.rs new file mode 100644 index 000000000..df3495613 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/cross_test_trait_obj_sig.rs @@ -0,0 +1,9 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use diem_crypto::traits::*; + +fn main() { + let mut l: Vec> = vec![]; +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/small_kdf.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/small_kdf.rs new file mode 100644 index 000000000..2a5e85ff0 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/compilation/small_kdf.rs @@ -0,0 +1,9 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +fn main() { + // Test for ripemd160, output_length < 256 + let ripemd = diem_crypto::hkdf::Hkdf::::extract(None, &[]); + assert!(ripemd.is_ok()); +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/cross_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/cross_test.rs new file mode 100644 index 000000000..6ebc0fb94 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/cross_test.rs @@ -0,0 +1,130 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +// This is necessary for the derive macros which rely on being used in a +// context where the crypto crate is external +use crate as diem_crypto; +use crate::{ + ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature}, + multi_ed25519::{MultiEd25519PrivateKey, MultiEd25519PublicKey, MultiEd25519Signature}, + test_utils::{random_serializable_struct, uniform_keypair_strategy}, + traits::*, +}; +use diem_crypto_derive::{ + PrivateKey, PublicKey, Signature, SigningKey, SilentDebug, ValidCryptoMaterial, VerifyingKey, +}; +use proptest::prelude::*; +use serde::{Deserialize, Serialize}; + +// Here we aim to make a point about how we can build an enum generically +// on top of a few choice signing scheme types. This enum implements the +// VerifyingKey, SigningKey for precisely the types selected for that enum +// (here, Ed25519(PublicKey|PrivateKey|Signature) and MultiEd25519(...)). +// +// Note that we do not break type safety (see towards the end), and that +// this enum can safely be put into the usual collection (Vec, HashMap). +// + +#[derive( + Serialize, + Deserialize, + Debug, + Clone, + PartialEq, + Eq, + Hash, + ValidCryptoMaterial, + PublicKey, + VerifyingKey, +)] +#[PrivateKeyType = "PrivateK"] +#[SignatureType = "Sig"] +enum PublicK { + Ed(Ed25519PublicKey), + MultiEd(MultiEd25519PublicKey), +} + +#[derive(Serialize, Deserialize, SilentDebug, ValidCryptoMaterial, PrivateKey, SigningKey)] +#[PublicKeyType = "PublicK"] +#[SignatureType = "Sig"] +enum PrivateK { + Ed(Ed25519PrivateKey), + MultiEd(MultiEd25519PrivateKey), +} + +#[allow(clippy::large_enum_variant)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Signature)] +#[PublicKeyType = "PublicK"] +#[PrivateKeyType = "PrivateK"] +enum Sig { + Ed(Ed25519Signature), + MultiEd(MultiEd25519Signature), +} + +/////////////////////////////////////////////////////// +// End of declarations — let's now prove type safety // +/////////////////////////////////////////////////////// +proptest! { + #![proptest_config(ProptestConfig::with_cases(20))] + + #[test] + #[allow(deprecated)] + fn test_keys_mix( + message in random_serializable_struct(), + ed_keypair1 in uniform_keypair_strategy::(), + ed_keypair2 in uniform_keypair_strategy::(), + med_keypair in uniform_keypair_strategy::() + ) { + // this is impossible to write statically, due to the trait not being + // object-safe (voluntarily), see unsupported_sigs below + // let mut l: Vec> = vec![]; + let mut l: Vec = vec![ed_keypair1.private_key]; + let ed_key = l.pop().unwrap(); + let signature = ed_key.sign(&message); + + // This is business as usual + prop_assert!(signature.verify(&message, &ed_keypair1.public_key).is_ok()); + + // signature-publickey mixups are statically impossible, see unsupported_sigs below + let mut l2: Vec = vec![ + PrivateK::MultiEd(med_keypair.private_key), + PrivateK::Ed(ed_keypair2.private_key), + ]; + + let ed_key = l2.pop().unwrap(); + let ed_signature = ed_key.sign(&message); + + // This is still business as usual + let ed_pubkey2 = PublicK::Ed(ed_keypair2.public_key); + let good_sigver = ed_signature.verify(&message, &ed_pubkey2); + prop_assert!(good_sigver.is_ok(), "{:?}", good_sigver); + + // but this still fails, as expected + let med_pubkey = PublicK::MultiEd(med_keypair.public_key); + let bad_sigver = ed_signature.verify(&message, &med_pubkey); + prop_assert!(bad_sigver.is_err(), "{:?}", bad_sigver); + + // And now just in case we're confused again, we pop in the + // reverse direction + let med_key = l2.pop().unwrap(); + let med_signature = med_key.sign(&message); + + // This is still business as usual + let good_sigver = med_signature.verify(&message, &med_pubkey); + prop_assert!(good_sigver.is_ok(), "{:?}", good_sigver); + + // but this still fails, as expected + let bad_sigver = med_signature.verify(&message, &ed_pubkey2); + prop_assert!(bad_sigver.is_err(), "{:?}", bad_sigver); + } +} + +#[test] +fn unsupported_sigs() { + let t = trybuild::TestCases::new(); + t.compile_fail("src/unit_tests/compilation/cross_test.rs"); + t.compile_fail("src/unit_tests/compilation/cross_test_trait_obj.rs"); + t.compile_fail("src/unit_tests/compilation/cross_test_trait_obj_sig.rs"); + t.compile_fail("src/unit_tests/compilation/cross_test_trait_obj_pub.rs"); +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/cryptohasher.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/cryptohasher.rs new file mode 100644 index 000000000..cd205e4a1 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/cryptohasher.rs @@ -0,0 +1,109 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! Test file for the procedural macros CryptoHasher and BCSCryptoHash. + +use crate as diem_crypto; +use crate::{ + hash::{CryptoHash, CryptoHasher, DIEM_HASH_PREFIX}, + HashValue, +}; +use diem_crypto_derive::{BCSCryptoHash, CryptoHasher}; +use serde::{Deserialize, Serialize}; +use tiny_keccak::{Hasher, Sha3}; + +// The expected use case. +#[derive(Serialize, Deserialize, CryptoHasher, BCSCryptoHash)] +pub struct Foo { + a: u64, + b: u32, +} + +// Used for testing the seed in FooHasher. +pub struct Bar {} + +// Complex example with generics and serde-rename. +#[derive(Serialize, Deserialize, CryptoHasher, BCSCryptoHash)] +#[serde(rename = "Foo")] +pub struct Baz { + a: T, + b: u32, +} + +impl CryptoHash for Bar { + type Hasher = FooHasher; + + fn hash(&self) -> HashValue { + let state = Self::Hasher::default(); + state.finish() + } +} + +#[test] +fn test_cryptohasher_name() { + let mut salt = DIEM_HASH_PREFIX.to_vec(); + salt.extend_from_slice(b"Foo"); + + let value = Bar {}; + let expected = { + let mut digest = Sha3::v256(); + digest.update(HashValue::sha3_256_of(&salt[..]).as_ref()); + let mut hasher_bytes = [0u8; 32]; + digest.finalize(&mut hasher_bytes); + hasher_bytes + }; + let actual = CryptoHash::hash(&value); + assert_eq!(&expected, actual.as_ref()); +} + +#[test] +fn test_bcs_cryptohash() { + let mut salt = DIEM_HASH_PREFIX.to_vec(); + salt.extend_from_slice(b"Foo"); + + let value = Foo { a: 5, b: 1025 }; + let expected = { + let mut digest = Sha3::v256(); + digest.update(HashValue::sha3_256_of(&salt[..]).as_ref()); + digest.update(&bcs::to_bytes(&value).unwrap()); + let mut hasher_bytes = [0u8; 32]; + digest.finalize(&mut hasher_bytes); + hasher_bytes + }; + let actual = CryptoHash::hash(&value); + assert_eq!(&expected, actual.as_ref()); +} + +#[test] +fn test_bcs_cryptohash_with_generics() { + let value = Baz { a: 5u64, b: 1025 }; + let expected = CryptoHash::hash(&Foo { a: 5, b: 1025 }); + let actual = CryptoHash::hash(&value); + assert_eq!(expected, actual); +} + +fn prefixed_sha3(input: &[u8]) -> [u8; 32] { + let mut sha3 = ::tiny_keccak::Sha3::v256(); + let salt: Vec = [DIEM_HASH_PREFIX, input].concat(); + sha3.update(&salt); + let mut output = [0u8; 32]; + sha3.finalize(&mut output); + output +} + +#[test] +fn test_cryptohasher_salt_access() { + // the salt for this simple struct is expected to be its name + assert_eq!(FooHasher::seed(), &prefixed_sha3(b"Foo")); + assert_eq!(::Hasher::seed(), &prefixed_sha3(b"Foo")); + assert_eq!( + as CryptoHash>::Hasher::seed(), + &prefixed_sha3(b"Foo") + ); + assert_eq!( + as CryptoHash>::Hasher::seed(), + &prefixed_sha3(b"Foo") + ); + assert_eq!(::Hasher::seed(), &prefixed_sha3(b"Foo")); +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/ed25519_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/ed25519_test.rs new file mode 100644 index 000000000..3d1deee2f --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/ed25519_test.rs @@ -0,0 +1,610 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate as diem_crypto; +use crate::{ + ed25519::{ + Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature, ED25519_PRIVATE_KEY_LENGTH, + ED25519_PUBLIC_KEY_LENGTH, ED25519_SIGNATURE_LENGTH, + }, + test_utils::{random_serializable_struct, uniform_keypair_strategy}, + traits::*, + x25519, +}; +use core::{ + convert::TryFrom, + ops::{Add, Index, IndexMut, Mul, Neg}, +}; +use diem_crypto_derive::{BCSCryptoHash, CryptoHasher}; +use digest::Digest; +use ed25519_dalek::ed25519::signature::{Signature as _, Verifier as _}; +use proptest::{collection::vec, prelude::*}; +use serde::{Deserialize, Serialize}; +use sha2::Sha512; + +#[derive(CryptoHasher, BCSCryptoHash, Serialize, Deserialize)] +struct CryptoHashable(pub usize); + +// Takes a point in eight_torsion and finds its order +fn eight_torsion_order(ep: curve25519_dalek::edwards::EdwardsPoint) -> usize { + let mut pt = ep; + let mut ord = 1; + for _i in 0..8 { + if pt == curve25519_dalek::edwards::EdwardsPoint::default() { + break; + } else { + pt = pt.add(ep); + ord += 1; + } + } + ord +} + +proptest! { + #[test] + fn verify_canonicity_torsion(scalar in any::<[u8;32]>(), idx in 0usize..8usize){ + let s = curve25519_dalek::scalar::Scalar::from_bytes_mod_order(scalar); + let s_b = curve25519_dalek::constants::ED25519_BASEPOINT_POINT.mul(s); + let torsion_component = curve25519_dalek::edwards::CompressedEdwardsY(EIGHT_TORSION[idx]).decompress().unwrap(); + let torsioned = s_b.add(torsion_component); + let torsioned_bytes = torsioned.compress().to_bytes(); + let deserialized = curve25519_dalek::edwards::CompressedEdwardsY(torsioned_bytes).decompress().unwrap(); + prop_assert_eq!(deserialized, torsioned); + } + + + #[test] + fn verify_mul_torsion(idx in 0usize..8usize){ + let torsion_component = curve25519_dalek::edwards::CompressedEdwardsY(EIGHT_TORSION[idx]).decompress().unwrap(); + let mut order_bytes = [0u8;32]; + order_bytes[..8].copy_from_slice(&(eight_torsion_order(torsion_component)).to_le_bytes()); + let torsion_order = curve25519_dalek::scalar::Scalar::from_bits(order_bytes); + + prop_assert_eq!(torsion_component.mul(torsion_order), curve25519_dalek::edwards::EdwardsPoint::default()); + } + + // In this test we demonstrate a signature that's not message-bound by only + // modifying the public key and the R component, under a pathological yet + // admissible s < l value for the signature + #[test] + fn verify_sig_malleable_torsion(keypair in uniform_keypair_strategy::(), idx in 0usize..8usize){ + let message = b"hello_world"; + /////////////////////////////////// + // baseline signature components // + /////////////////////////////////// + let pub_key_bytes = keypair.public_key.to_bytes(); + let priv_key_bytes = keypair.private_key.to_bytes(); + let pub_key = ed25519_dalek::PublicKey::from_bytes(&pub_key_bytes).unwrap(); + let secret_key = ed25519_dalek::SecretKey::from_bytes(&priv_key_bytes).unwrap(); + let priv_key = ed25519_dalek::ExpandedSecretKey::from(&secret_key); + let signature = priv_key.sign(&message[..], &pub_key); + prop_assert!(pub_key.verify(&message[..], &signature).is_ok()); + + let torsion_component = curve25519_dalek::edwards::CompressedEdwardsY(EIGHT_TORSION[idx]).decompress().unwrap(); + + let mut r_bits = [0u8; 32]; + r_bits.copy_from_slice(&signature.to_bytes()[..32]); + + let r_point = curve25519_dalek::edwards::CompressedEdwardsY(r_bits).decompress().unwrap(); + let mixed_r_point = r_point.add(torsion_component); + prop_assert_eq!(r_point.mul_by_cofactor(), mixed_r_point.mul_by_cofactor()); + + let pub_point = curve25519_dalek::edwards::CompressedEdwardsY(pub_key_bytes).decompress().unwrap(); + let mixed_pub_point = pub_point.add(torsion_component); + prop_assert_eq!(pub_point.mul_by_cofactor(), mixed_pub_point.mul_by_cofactor()); + + ////////////////////////// + // Compute k = H(R∥A∥m) // + ////////////////////////// + let mut h: Sha512 = Sha512::default(); + h.update(mixed_r_point.compress().to_bytes()); + h.update(mixed_pub_point.compress().to_bytes()); + h.update(message); + // curve25519_dalek is stuck on an old digest version, so we can't do + // Scalar::from_hash + let mut output = [0u8; 64]; + output.copy_from_slice(h.finalize().as_slice()); + let k = curve25519_dalek::scalar::Scalar::from_bytes_mod_order_wide(&output); + + ////////////////////////////////////////////////////////////// + // obtain the original r s.t. R = r B, to solve for s later // + ////////////////////////////////////////////////////////////// + let mut expanded_priv_key = [0u8; 64]; + let mut h: Sha512 = Sha512::default(); + h.update(priv_key_bytes); + expanded_priv_key.copy_from_slice(h.finalize().as_slice()); + + let nonce = &expanded_priv_key[32..]; + let mut h: Sha512 = Sha512::default(); + h.update(nonce); + h.update(message); + // curve25519_dalek is stuck on an old digest version, so we can't do + // Scalar::from_hash + let mut output = [0u8; 64]; + output.copy_from_slice(h.finalize().as_slice()); + let original_r = curve25519_dalek::scalar::Scalar::from_bytes_mod_order_wide(&output); + + // check r_point = original_r * basepoint + prop_assert_eq!(curve25519_dalek::constants::ED25519_BASEPOINT_POINT.mul(original_r), r_point); + + ////////////////////////////////////////// + // obtain the original a s.t. a * B = A // + ////////////////////////////////////////// + let mut key_bytes = [0u8;32]; + key_bytes.copy_from_slice(&expanded_priv_key[..32]); + key_bytes[0] &= 248; + key_bytes[31] &= 127; + key_bytes[31] |= 64; + let priv_scalar = curve25519_dalek::scalar::Scalar::from_bits(key_bytes); + // check pub_point = priv_scalar * basepoint + prop_assert_eq!(curve25519_dalek::constants::ED25519_BASEPOINT_POINT.mul(priv_scalar), pub_point); + + ////////////////////////// + // s = r + k a as usual // + ////////////////////////// + let s = k * priv_scalar + original_r; + prop_assert!(s.is_canonical()); + + ///////////////////////////////////////////////////////////////////////////////// + // Check the cofactored equation (modulo 8) before conversion to dalek formats // + ///////////////////////////////////////////////////////////////////////////////// + let mut eight_scalar_bytes = [0u8;32]; + eight_scalar_bytes[..8].copy_from_slice(&(8_usize).to_le_bytes()); + let eight_scalar = curve25519_dalek::scalar::Scalar::from_bits(eight_scalar_bytes); + + let r_candidate_point = curve25519_dalek::edwards::EdwardsPoint::vartime_double_scalar_mul_basepoint(&k, &(mixed_pub_point.neg().mul_by_cofactor()), &(s * eight_scalar)); + prop_assert_eq!(mixed_r_point.mul_by_cofactor(), r_candidate_point); + + /////////////////////////////////////////////////////////// + // convert byte strings in dalek terms and do API checks // + /////////////////////////////////////////////////////////// + let mixed_pub_key = ed25519_dalek::PublicKey::from_bytes(&mixed_pub_point.compress().to_bytes()).unwrap(); + // check we would not have caught this mixed order point on PublicKey deserialization + prop_assert!(Ed25519PublicKey::try_from(&mixed_pub_point.compress().to_bytes()[..]).is_ok()); + + let mixed_signature_bits : Vec = [mixed_r_point.compress().to_bytes(), s.to_bytes()].concat(); + // this will error if we don't have 0 ≤ s < l + let mixed_signature = ed25519_dalek::Signature::from_bytes(&mixed_signature_bits).unwrap(); + + // Check, however, that dalek is doing the raw equation check sB = R + kA + let permissive_passes = mixed_pub_key.verify(&message[..], &mixed_signature).is_ok(); + let strict_passes = mixed_pub_key.verify_strict(&message[..], &mixed_signature).is_ok(); + + let torsion_order = eight_torsion_order(torsion_component); + let torsion_components_cancel = torsion_component + k * torsion_component == curve25519_dalek::edwards::EdwardsPoint::default(); + + prop_assert!(!permissive_passes || (torsion_order == 1) || torsion_components_cancel, + "bad verification_state permissive passes {} strict passes {} mixed_order {:?} torsion_components_cancel {:?}", + permissive_passes, + strict_passes, + torsion_order, + torsion_components_cancel + ); + } + + // In this test we demonstrate a signature that's transformable by only + // modifying the public key and the R component, under a pathological yet + // admissible s < l value for the signature. It shows the difference + // between `verify` and `verify_strict` in ed25519-dalek + #[test] + fn verify_sig_strict_torsion(idx in 0usize..8usize){ + let message = b"hello_world"; + + // Dalek only performs an order check, so this is allowed + let bad_scalar = curve25519_dalek::scalar::Scalar::zero(); + + let bad_component_1 = curve25519_dalek::edwards::CompressedEdwardsY(EIGHT_TORSION[idx]).decompress().unwrap(); + let bad_component_2 = bad_component_1.neg(); + + // compute bad_pub_key, bad_signature + let bad_pub_key_point = bad_component_1; // we need this to cancel the hashed component of the verification equation + + // we pick an evil R component + let bad_sig_point = bad_component_2; + + let bad_key = ed25519_dalek::PublicKey::from_bytes(&bad_pub_key_point.compress().to_bytes()).unwrap(); + // We check that we would have caught this one on the public key + prop_assert!(Ed25519PublicKey::try_from(&bad_pub_key_point.compress().to_bytes()[..]).is_err()); + + let bad_signature = ed25519_dalek::Signature::from_bytes(&[ + &bad_sig_point.compress().to_bytes()[..], + &bad_scalar.to_bytes()[..] + ].concat()).unwrap(); + + // Seek k = H(R, A, M) ≡ 1 [8] + prop_assume!(bad_key.verify(&message[..], &bad_signature).is_ok()); + prop_assert!(bad_key.verify_strict(&message[..], &bad_signature).is_err()); + + } + + + #[test] + fn convert_from_ed25519_publickey(keypair in uniform_keypair_strategy::()) { + let x25519_public_key = x25519::PublicKey::from_ed25519_public_bytes(&keypair.public_key.to_bytes()[..]).unwrap(); + + // Let's construct an x25519 private key from the ed25519 private key. + let x25519_privatekey = x25519::PrivateKey::from_ed25519_private_bytes(&keypair.private_key.to_bytes()[..]); + + // This is the important part! We abandon the entire test if an x25519 private + // key can't be built from this ed25519 private key, thus "grinding" + // the RNG. + if x25519_privatekey.is_ok() { + // Now derive the public key from x25519_privatekey and see if it matches the public key that + // was created from the Ed25519PublicKey. + let x25519_publickey_2 = x25519_privatekey.unwrap().public_key(); + assert_eq!(x25519_public_key, x25519_publickey_2); + } + } + + #[test] + fn ed25519_and_x25519_privkeys(keypair in uniform_keypair_strategy::()){ + let x25519_public_bytes = keypair.public_key.to_bytes(); + let x25519_private_bytes = keypair.private_key.to_bytes(); + //sanity-check + prop_assert_eq!(x25519_public_bytes.clone(), x25519::PublicKey::from(&keypair.private_key).to_bytes()); + + // always pass false if you hope to ever get back to the original public key + let ed25519_public = Ed25519PublicKey::from_x25519_public_bytes(&x25519_public_bytes, false).unwrap(); + let x25519_backconverted_public = x25519::PublicKey::from_ed25519_public_bytes(&ed25519_public.to_bytes()[..]).unwrap(); + + let ed25519_private = Ed25519PrivateKey::try_from(&x25519_private_bytes[..]).unwrap(); + let x25519_backconverted_private = x25519::PrivateKey::try_from(&ed25519_private.to_bytes()[..]).unwrap(); + + // Test that you can always retrieve a valid x25519 keypair after + // "serialization" as an ed25519 keypair + prop_assert_eq!(keypair.public_key, x25519_backconverted_public); + prop_assert_eq!(keypair.private_key, x25519_backconverted_private.clone()); + prop_assert_eq!(x25519_backconverted_public, x25519::PublicKey::from(&x25519_backconverted_private)); + // Note that the reverse is not true: converting to an x25519 private + // key mangles the ed25519 private key bits irreversibly ! + } + + #[test] + fn ed25519_to_x25519_roundtrip(keypair in uniform_keypair_strategy::()){ + let ed25519_bytes = keypair.public_key.to_bytes(); + let x25519 = x25519::PublicKey::from_ed25519_public_bytes(&ed25519_bytes).unwrap(); + let x25519_bytes = x25519.as_slice(); + let backconverted_ed_positive = Ed25519PublicKey::from_x25519_public_bytes(x25519_bytes, false).unwrap(); + let backconverted_ed_negative = Ed25519PublicKey::from_x25519_public_bytes(x25519_bytes, true).unwrap(); + prop_assert!(keypair.public_key == backconverted_ed_negative || keypair.public_key == backconverted_ed_positive); + } + + #[test] + fn test_pub_key_deserialization(bits in any::<[u8; 32]>()){ + let pt_deser = curve25519_dalek::edwards::CompressedEdwardsY(bits).decompress(); + let pub_key = Ed25519PublicKey::try_from(&bits[..]); + let check = matches!((pt_deser, pub_key), + (Some(_), Ok(_)) // we agree with Dalek, + | (Some(_), Err(CryptoMaterialError::SmallSubgroupError)) // dalek does not detect pubkeys in a small subgroup, + | (None, Err(CryptoMaterialError::DeserializationError)) // we agree on point decompression failures, + ); + prop_assert!(check); + } + + #[test] + fn test_keys_encode(keypair in uniform_keypair_strategy::()) { + { + let encoded = keypair.private_key.to_encoded_string().unwrap(); + // Hex encoding of a 32-bytes key is 64 (2 x 32) characters. + prop_assert_eq!(2 * ED25519_PRIVATE_KEY_LENGTH, encoded.len()); + let decoded = Ed25519PrivateKey::from_encoded_string(&encoded); + prop_assert_eq!(Some(keypair.private_key), decoded.ok()); + } + { + let encoded = keypair.public_key.to_encoded_string().unwrap(); + // Hex encoding of a 32-bytes key is 64 (2 x 32) characters. + prop_assert_eq!(2 * ED25519_PUBLIC_KEY_LENGTH, encoded.len()); + let decoded = Ed25519PublicKey::from_encoded_string(&encoded); + prop_assert_eq!(Some(keypair.public_key), decoded.ok()); + } + } + + #[test] + fn test_batch_verify( + message in random_serializable_struct(), + keypairs in proptest::array::uniform10(uniform_keypair_strategy::()) + ) { + let mut signatures: Vec<(Ed25519PublicKey, Ed25519Signature)> = keypairs.iter().map(|keypair| { + (keypair.public_key.clone(), keypair.private_key.sign(&message)) + }).collect(); + prop_assert!(Ed25519Signature::batch_verify(&message, signatures.clone()).is_ok()); + // We swap message and signature for the last element, + // resulting in an incorrect signature + let (key, _sig) = signatures.pop().unwrap(); + let other_sig = signatures.last().unwrap().clone().1; + signatures.push((key, other_sig)); + prop_assert!(Ed25519Signature::batch_verify(&message, signatures).is_err()); + } + + #[test] + fn test_keys_custom_serialisation( + keypair in uniform_keypair_strategy::() + ) { + { + let serialized: &[u8] = &(keypair.private_key.to_bytes()); + prop_assert_eq!(ED25519_PRIVATE_KEY_LENGTH, serialized.len()); + let deserialized = Ed25519PrivateKey::try_from(serialized); + prop_assert_eq!(Some(keypair.private_key), deserialized.ok()); + } + { + let serialized: &[u8] = &(keypair.public_key.to_bytes()); + prop_assert_eq!(ED25519_PUBLIC_KEY_LENGTH, serialized.len()); + let deserialized = Ed25519PublicKey::try_from(serialized); + prop_assert_eq!(Some(keypair.public_key), deserialized.ok()); + } + } + + #[test] + fn test_signature_verification_custom_serialisation( + message in random_serializable_struct(), + keypair in uniform_keypair_strategy::() + ) { + let signature = keypair.private_key.sign(&message); + let serialized: &[u8] = &(signature.to_bytes()); + prop_assert_eq!(ED25519_SIGNATURE_LENGTH, serialized.len()); + let deserialized = Ed25519Signature::try_from(serialized).unwrap(); + prop_assert!(deserialized.verify(&message, &keypair.public_key).is_ok()); + } + + #[test] + fn test_signature_verification_from_arbitrary( + // this should be > 64 bits to go over the length of a default hash + msg in vec(proptest::num::u8::ANY, 1..128), + keypair in uniform_keypair_strategy::() + ) { + let signature = keypair.private_key.sign_arbitrary_message(&msg); + let serialized: &[u8] = &(signature.to_bytes()); + prop_assert_eq!(ED25519_SIGNATURE_LENGTH, serialized.len()); + let deserialized = Ed25519Signature::try_from(serialized).unwrap(); + prop_assert!(deserialized.verify_arbitrary_msg(&msg, &keypair.public_key).is_ok()); + } + + #[test] + fn test_signature_verification_from_struct( + x in any::(), + keypair in uniform_keypair_strategy::() + ) { + let hashable = CryptoHashable(x); + let signature = keypair.private_key.sign(&hashable); + let serialized: &[u8] = &(signature.to_bytes()); + prop_assert_eq!(ED25519_SIGNATURE_LENGTH, serialized.len()); + let deserialized = Ed25519Signature::try_from(serialized).unwrap(); + prop_assert!(deserialized.verify(&hashable, &keypair.public_key).is_ok()); + } + + + // Check for canonical S. + #[test] + fn test_signature_malleability( + message in random_serializable_struct(), + keypair in uniform_keypair_strategy::() + ) { + let signature = keypair.private_key.sign(&message); + let mut serialized = signature.to_bytes(); + + let mut r_bytes: [u8; 32] = [0u8; 32]; + r_bytes.copy_from_slice(&serialized[..32]); + + let mut s_bytes: [u8; 32] = [0u8; 32]; + s_bytes.copy_from_slice(&serialized[32..]); + + // ed25519-dalek signing ensures a canonical S value. + let s = Scalar52::from_bytes(&s_bytes); + + // adding L (order of the base point) so that S + L > L + let malleable_s = Scalar52::add(&s, &L); + let malleable_s_bytes = malleable_s.to_bytes(); + // Update the signature (the S part). + serialized[32..].copy_from_slice(&malleable_s_bytes); + + // Check that malleable signatures will pass verification and deserialization in dalek. + // Construct the corresponding dalek public key. + let _dalek_public_key = ed25519_dalek::PublicKey::from_bytes( + &keypair.public_key.to_bytes() + ).unwrap(); + + // Construct the corresponding dalek Signature. This signature is malleable. + let dalek_sig = ed25519_dalek::Signature::from_bytes(&serialized); + + // ed25519_dalek will (post 2.0) deserialize the malleable + // signature. It does not detect it. + prop_assert!(dalek_sig.is_ok()); + + let serialized_malleable: &[u8] = &serialized; + // try_from will fail on malleable signatures. We detect malleable signatures + // during deserialization. + prop_assert_eq!( + Ed25519Signature::try_from(serialized_malleable), + Err(CryptoMaterialError::CanonicalRepresentationError) + ); + + // We expect from_bytes_unchecked deserialization to succeed, as dalek + // does not check for signature malleability. This method is pub(crate) + // and only used for test purposes. + let sig_unchecked = Ed25519Signature::from_bytes_unchecked(&serialized); + prop_assert!(sig_unchecked.is_ok()); + + // Update the signature by setting S = L to make it invalid. + serialized[32..].copy_from_slice(&L.to_bytes()); + let serialized_malleable_l: &[u8] = &serialized; + // try_from will fail with CanonicalRepresentationError. + prop_assert_eq!( + Ed25519Signature::try_from(serialized_malleable_l), + Err(CryptoMaterialError::CanonicalRepresentationError) + ); + } +} + +// Test against known small subgroup public keys. +#[test] +fn test_publickey_smallorder() { + for torsion_point in &EIGHT_TORSION { + let serialized: &[u8] = torsion_point; + // We expect from_bytes_unchecked to pass, as it does not validate the key. + assert!(Ed25519PublicKey::from_bytes_unchecked(serialized).is_ok()); + // from_bytes will fail on invalid key. + assert_eq!( + Ed25519PublicKey::try_from(serialized), + Err(CryptoMaterialError::SmallSubgroupError) + ); + } +} + +// The 8-torsion subgroup E[8]. +// +// In the case of Curve25519, it is cyclic; the i-th element of +// the array is [i]P, where P is a point of order 8 +// generating E[8]. +// +// Thus E[8] is the points indexed by `0,2,4,6`, and +// E[2] is the points indexed by `0,4`. +// +// The following byte arrays have been ported from curve25519-dalek /backend/serial/u64/constants.rs +// and they represent the serialised version of the CompressedEdwardsY points. + +const EIGHT_TORSION: [[u8; 32]; 8] = [ + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + ], + [ + 199, 23, 106, 112, 61, 77, 216, 79, 186, 60, 11, 118, 13, 16, 103, 15, 42, 32, 83, 250, 44, + 57, 204, 198, 78, 199, 253, 119, 146, 172, 3, 122, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, + ], + [ + 38, 232, 149, 143, 194, 178, 39, 176, 69, 195, 244, 137, 242, 239, 152, 240, 213, 223, 172, + 5, 211, 198, 51, 57, 177, 56, 2, 136, 109, 83, 252, 5, + ], + [ + 236, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, + ], + [ + 38, 232, 149, 143, 194, 178, 39, 176, 69, 195, 244, 137, 242, 239, 152, 240, 213, 223, 172, + 5, 211, 198, 51, 57, 177, 56, 2, 136, 109, 83, 252, 133, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + ], + [ + 199, 23, 106, 112, 61, 77, 216, 79, 186, 60, 11, 118, 13, 16, 103, 15, 42, 32, 83, 250, 44, + 57, 204, 198, 78, 199, 253, 119, 146, 172, 3, 250, + ], +]; + +/// The `Scalar52` struct represents an element in +/// ℤ/ℓℤ as 5 52-bit limbs. +struct Scalar52(pub [u64; 5]); + +/// `L` is the order of base point, i.e. 2^252 + 27742317777372353535851937790883648493 +const L: Scalar52 = Scalar52([ + 0x0002_631A_5CF5_D3ED, + 0x000D_EA2F_79CD_6581, + 0x0000_0000_0014_DEF9, + 0x0000_0000_0000_0000, + 0x0000_1000_0000_0000, +]); + +impl Scalar52 { + /// Return the zero scalar + fn zero() -> Scalar52 { + Scalar52([0, 0, 0, 0, 0]) + } + + /// Unpack a 32 byte / 256 bit scalar into 5 52-bit limbs. + fn from_bytes(bytes: &[u8; 32]) -> Scalar52 { + let mut words = [0u64; 4]; + for i in 0..4 { + for j in 0..8 { + words[i] |= u64::from(bytes[(i * 8) + j]) << (j * 8) as u64; + } + } + + let mask = (1u64 << 52) - 1; + let top_mask = (1u64 << 48) - 1; + let mut s = Scalar52::zero(); + + s[0] = words[0] & mask; + s[1] = ((words[0] >> 52) | (words[1] << 12)) & mask; + s[2] = ((words[1] >> 40) | (words[2] << 24)) & mask; + s[3] = ((words[2] >> 28) | (words[3] << 36)) & mask; + s[4] = (words[3] >> 16) & top_mask; + + s + } + + /// Pack the limbs of this `Scalar52` into 32 bytes + fn to_bytes(&self) -> [u8; 32] { + let mut s = [0u8; 32]; + + s[0] = self.0[0] as u8; + s[1] = (self.0[0] >> 8) as u8; + s[2] = (self.0[0] >> 16) as u8; + s[3] = (self.0[0] >> 24) as u8; + s[4] = (self.0[0] >> 32) as u8; + s[5] = (self.0[0] >> 40) as u8; + s[6] = ((self.0[0] >> 48) | (self.0[1] << 4)) as u8; + s[7] = (self.0[1] >> 4) as u8; + s[8] = (self.0[1] >> 12) as u8; + s[9] = (self.0[1] >> 20) as u8; + s[10] = (self.0[1] >> 28) as u8; + s[11] = (self.0[1] >> 36) as u8; + s[12] = (self.0[1] >> 44) as u8; + s[13] = self.0[2] as u8; + s[14] = (self.0[2] >> 8) as u8; + s[15] = (self.0[2] >> 16) as u8; + s[16] = (self.0[2] >> 24) as u8; + s[17] = (self.0[2] >> 32) as u8; + s[18] = (self.0[2] >> 40) as u8; + s[19] = ((self.0[2] >> 48) | (self.0[3] << 4)) as u8; + s[20] = (self.0[3] >> 4) as u8; + s[21] = (self.0[3] >> 12) as u8; + s[22] = (self.0[3] >> 20) as u8; + s[23] = (self.0[3] >> 28) as u8; + s[24] = (self.0[3] >> 36) as u8; + s[25] = (self.0[3] >> 44) as u8; + s[26] = self.0[4] as u8; + s[27] = (self.0[4] >> 8) as u8; + s[28] = (self.0[4] >> 16) as u8; + s[29] = (self.0[4] >> 24) as u8; + s[30] = (self.0[4] >> 32) as u8; + s[31] = (self.0[4] >> 40) as u8; + + s + } + + /// Compute `a + b` (without mod ℓ) + fn add(a: &Scalar52, b: &Scalar52) -> Scalar52 { + let mut sum = Scalar52::zero(); + let mask = (1u64 << 52) - 1; + + // a + b + let mut carry: u64 = 0; + for i in 0..5 { + carry = a[i] + b[i] + (carry >> 52); + sum[i] = carry & mask; + } + + sum + } +} + +impl Index for Scalar52 { + type Output = u64; + + fn index(&self, _index: usize) -> &u64 { + &(self.0[_index]) + } +} + +impl IndexMut for Scalar52 { + fn index_mut(&mut self, _index: usize) -> &mut u64 { + &mut (self.0[_index]) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/hash_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/hash_test.rs new file mode 100644 index 000000000..bd20d397c --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/hash_test.rs @@ -0,0 +1,250 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::hash::*; +use bitvec::prelude::*; +use proptest::{collection::vec, prelude::*}; +use rand::{rngs::StdRng, SeedableRng}; +use serde::Serialize; +use std::str::FromStr; + +#[derive(Serialize)] +struct Foo(u32); + +#[test] +fn test_default_hasher() { + assert_eq!( + Foo(3).test_only_hash(), + HashValue::from_iter_sha3(vec![bcs::to_bytes(&Foo(3)).unwrap().as_slice()]), + ); + assert_eq!( + format!("{:x}", b"hello".test_only_hash()), + "3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392", + ); + assert_eq!( + format!("{:x}", b"world".test_only_hash()), + "420baf620e3fcd9b3715b42b92506e9304d56e02d3a103499a3a292560cb66b2", + ); +} + +#[test] +fn test_primitive_type() { + let x = 0xF312_u16; + let mut wtr: Vec = vec![]; + wtr.extend_from_slice(&x.to_le_bytes()); + assert_eq!(x.test_only_hash(), HashValue::sha3_256_of(&wtr[..])); + + let x = 0xFF00_1234_u32; + let mut wtr: Vec = vec![]; + wtr.extend_from_slice(&x.to_le_bytes()); + assert_eq!(x.test_only_hash(), HashValue::sha3_256_of(&wtr[..])); + + let x = 0x89AB_CDEF_0123_4567_u64; + let mut wtr: Vec = vec![]; + wtr.extend_from_slice(&x.to_le_bytes()); + assert_eq!(x.test_only_hash(), HashValue::sha3_256_of(&wtr[..])); +} + +#[test] +fn test_from_slice() { + { + let zero_byte_vec = vec![0; 32]; + assert_eq!( + HashValue::from_slice(zero_byte_vec).unwrap(), + HashValue::zero() + ); + } + { + // The length is mismatched. + let zero_byte_vec = vec![0; 31]; + assert!(HashValue::from_slice(zero_byte_vec).is_err()); + } + { + let bytes = vec![1; 123]; + assert!(HashValue::from_slice(&bytes[..]).is_err()); + } +} + +#[test] +fn test_random_with_rng() { + let mut seed = [0u8; 32]; + seed[..4].copy_from_slice(&[1, 2, 3, 4]); + let hash1; + let hash2; + { + let mut rng: StdRng = SeedableRng::from_seed(seed); + hash1 = HashValue::random_with_rng(&mut rng); + } + { + let mut rng: StdRng = SeedableRng::from_seed(seed); + hash2 = HashValue::random_with_rng(&mut rng); + } + assert_eq!(hash1, hash2); +} + +#[test] +#[allow(clippy::bool_assert_comparison)] +fn test_hash_value_iter_bits() { + let hash = b"hello".test_only_hash(); + let bits = hash.iter_bits().collect::>(); + + assert_eq!(bits.len(), HashValue::LENGTH_IN_BITS); + assert_eq!(bits[0], false); + assert_eq!(bits[1], false); + assert_eq!(bits[2], true); + assert_eq!(bits[3], true); + assert_eq!(bits[4], false); + assert_eq!(bits[5], false); + assert_eq!(bits[6], true); + assert_eq!(bits[7], true); + assert_eq!(bits[248], true); + assert_eq!(bits[249], false); + assert_eq!(bits[250], false); + assert_eq!(bits[251], true); + assert_eq!(bits[252], false); + assert_eq!(bits[253], false); + assert_eq!(bits[254], true); + assert_eq!(bits[255], false); + + let mut bits_rev = hash.iter_bits().rev().collect::>(); + bits_rev.reverse(); + assert_eq!(bits, bits_rev); +} + +#[test] +fn test_hash_value_iterator_exact_size() { + let hash = b"hello".test_only_hash(); + + let mut iter = hash.iter_bits(); + assert_eq!(iter.len(), HashValue::LENGTH_IN_BITS); + iter.next(); + assert_eq!(iter.len(), HashValue::LENGTH_IN_BITS - 1); + iter.next_back(); + assert_eq!(iter.len(), HashValue::LENGTH_IN_BITS - 2); + + let iter_rev = hash.iter_bits().rev(); + assert_eq!(iter_rev.len(), HashValue::LENGTH_IN_BITS); + + let iter_skip = hash.iter_bits().skip(100); + assert_eq!(iter_skip.len(), HashValue::LENGTH_IN_BITS - 100); +} + +#[test] +fn test_fmt_binary() { + let hash = b"hello".test_only_hash(); + let hash_str = format!("{:b}", hash); + assert_eq!(hash_str.len(), HashValue::LENGTH_IN_BITS); + for (bit, chr) in hash.iter_bits().zip(hash_str.chars()) { + assert_eq!(chr, if bit { '1' } else { '0' }); + } +} + +#[test] +fn test_get_nibble() { + let mut bytes = [0u8; HashValue::LENGTH]; + let mut nibbles = vec![]; + for byte in bytes.iter_mut().take(HashValue::LENGTH) { + *byte = rand::thread_rng().gen(); + nibbles.push(*byte >> 4); + nibbles.push(*byte & 0x0F); + } + let hash = HashValue::new(bytes); + for (i, nibble) in nibbles.iter().enumerate().take(HashValue::LENGTH * 2) { + assert_eq!(hash.nibble(i), *nibble); + } +} + +#[test] +fn test_common_prefix_bits_len() { + { + let hash1 = b"hello".test_only_hash(); + let hash2 = b"HELLO".test_only_hash(); + assert_eq!(hash1[0], 0b0011_0011); + assert_eq!(hash2[0], 0b1011_1000); + assert_eq!(hash1.common_prefix_bits_len(hash2), 0); + } + { + let hash1 = b"hello".test_only_hash(); + let hash2 = b"world".test_only_hash(); + assert_eq!(hash1[0], 0b0011_0011); + assert_eq!(hash2[0], 0b0100_0010); + assert_eq!(hash1.common_prefix_bits_len(hash2), 1); + } + { + let hash1 = b"hello".test_only_hash(); + let hash2 = b"100011001000".test_only_hash(); + assert_eq!(hash1[0], 0b0011_0011); + assert_eq!(hash2[0], 0b0011_0011); + assert_eq!(hash1[1], 0b0011_1000); + assert_eq!(hash2[1], 0b0010_0010); + assert_eq!(hash1.common_prefix_bits_len(hash2), 11); + } + { + let hash1 = b"hello".test_only_hash(); + let hash2 = b"hello".test_only_hash(); + assert_eq!( + hash1.common_prefix_bits_len(hash2), + HashValue::LENGTH_IN_BITS + ); + } +} + +proptest! { + #[test] + fn test_hashvalue_to_bits_roundtrip(hash in any::()) { + let bitvec: BitVec = hash.iter_bits().collect(); + let bytes: Vec = bitvec.into(); + let hash2 = HashValue::from_slice(bytes).unwrap(); + prop_assert_eq!(hash, hash2); + } + + #[test] + fn test_hashvalue_to_bits_inverse_roundtrip(bits in vec(any::(), HashValue::LENGTH_IN_BITS)) { + let bitvec: BitVec = bits.iter().cloned().collect(); + let bytes: Vec = bitvec.into(); + let hash = HashValue::from_slice(bytes).unwrap(); + let bits2: Vec = hash.iter_bits().collect(); + prop_assert_eq!(bits, bits2); + } + + #[test] + fn test_hashvalue_iter_bits_rev(hash in any::()) { + let bits1: Vec = hash.iter_bits().collect(); + let mut bits2: Vec = hash.iter_bits().rev().collect(); + bits2.reverse(); + prop_assert_eq!(bits1, bits2); + } + + #[test] + fn test_hashvalue_to_rev_bits_roundtrip(hash in any::()) { + let bitvec: BitVec = hash.iter_bits().rev().collect(); + let mut bytes: Vec = bitvec.into(); + bytes.reverse(); + let hash2 = HashValue::from_slice(&bytes).unwrap(); + prop_assert_eq!(hash, hash2); + } + + #[test] + fn test_hashvalue_to_str_roundtrip(hash in any::()) { + let hash2 = HashValue::from_str(&hash.to_hex()).unwrap(); + prop_assert_eq!(hash, hash2); + } + + #[test] + fn test_hashvalue_to_hex_literal(hash in any::()) { + prop_assert_eq!(format!("0x{}", hash.to_hex()), hash.to_hex_literal()); + } + + #[test] + fn test_hashvalue_from_bit_iter(hash in any::()) { + let hash2 = HashValue::from_bit_iter(hash.iter_bits()).unwrap(); + prop_assert_eq!(hash, hash2); + + let bits1 = vec![false; HashValue::LENGTH_IN_BITS - 10]; + prop_assert!(HashValue::from_bit_iter(bits1.into_iter()).is_err()); + + let bits2 = vec![false; HashValue::LENGTH_IN_BITS + 10]; + prop_assert!(HashValue::from_bit_iter(bits2.into_iter()).is_err()); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/hkdf_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/hkdf_test.rs new file mode 100644 index 000000000..a211e6c06 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/hkdf_test.rs @@ -0,0 +1,237 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{compat::Sha3_256, hkdf::*}; +use sha2::{Sha256, Sha512}; + +// Testing against sha256 test vectors. Unfortunately the rfc does not provide test vectors for +// sha3 and sha512. +#[test] +fn test_sha256_test_vectors() { + let tests = test_vectors_sha256(); + for t in tests.iter() { + let ikm = hex::decode(t.ikm).unwrap(); + let salt = hex::decode(t.salt).unwrap(); + let info = hex::decode(t.info).unwrap(); + + let hkdf_extract = Hkdf::::extract(Option::from(&salt[..]), &ikm[..]).unwrap(); + let hkdf_expand = Hkdf::::expand(&hkdf_extract, Some(&info[..]), t.length); + + assert!(hkdf_expand.is_ok()); + assert_eq!(t.prk, hex::encode(hkdf_extract)); + assert_eq!(t.okm, hex::encode(hkdf_expand.unwrap())); + } +} + +// Testing against sha256 test vectors for the extract_then_expand function. +#[test] +fn test_extract_then_expand() { + let tests = test_vectors_sha256(); + for t in tests.iter() { + let ikm = hex::decode(t.ikm).unwrap(); + let salt = hex::decode(t.salt).unwrap(); + let info = hex::decode(t.info).unwrap(); + + let hkdf_full = Hkdf::::extract_then_expand( + Option::from(&salt[..]), + &ikm[..], + Option::from(&info[..]), + t.length, + ); + + assert!(hkdf_full.is_ok()); + assert_eq!(t.okm, hex::encode(hkdf_full.unwrap())); + } +} + +#[test] +fn test_sha256_output_length() { + // According to rfc, max_sha256_length <= 255 * HashLen bytes + let max_hash_length: usize = 255 * 32; // = 8160 + let ikm = [0u8; 32]; + // We extract once, then we reuse it. + let hkdf_extract = Hkdf::::extract(None, &ikm).unwrap(); + + // Test for max allowed (expected to pass) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, max_hash_length); + assert!(hkdf_expand.is_ok()); + assert_eq!(hkdf_expand.unwrap().len(), max_hash_length); + + // Test for max + 1 (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, max_hash_length + 1); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); + + // Test for 10_000 > max (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, 10_000); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); + + // Test for zero size output (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, 0); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); +} + +// FIPS 202 approves HMAC-SHA3 and specifies the block sizes (see top of page 22). +// SP 800-56C approves of HKDF-HMAC-hash as a randomness extractor with any approved hash function. +// But in contrast, I can't find any NIST statement that explicitly approves the use of KMAC +// as a randomness extractor. +// But, it's debatable if this is a pointless construct, as HMAC only exists to cover up weaknesses +// in Merkle-Damgard hashes, but sha3 (and Keccak) are sponge constructions, immune to length +// extension attacks. +#[test] +fn test_sha3_256_output_length() { + let max_hash_length: usize = 255 * 32; // = 8160 + let ikm = [0u8; 32]; + let hkdf_extract = Hkdf::::extract(None, &ikm).unwrap(); + + // Test for max allowed (expected to pass) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, max_hash_length); + assert!(hkdf_expand.is_ok()); + assert_eq!(hkdf_expand.unwrap().len(), max_hash_length); + + // Test for max + 1 (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, max_hash_length + 1); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); + + // Test for 10_000 > max (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, 10_000); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); + + // Test for zero size output (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, 0); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); +} + +#[test] +fn test_sha512_output_length() { + let max_hash_length: usize = 255 * 64; // = 16320 + let ikm = [0u8; 32]; + let hkdf_extract = Hkdf::::extract(None, &ikm).unwrap(); + + // Test for max allowed (expected to pass) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, max_hash_length); + assert!(hkdf_expand.is_ok()); + assert_eq!(hkdf_expand.unwrap().len(), max_hash_length); + + // Test for max + 1 (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, max_hash_length + 1); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); + + // Test for 10_000 > max (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, 20_000); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); + + // Test for zero size output (expected to fail) + let hkdf_expand = Hkdf::::expand(&hkdf_extract, None, 0); + assert_eq!( + hkdf_expand.unwrap_err(), + HkdfError::InvalidOutputLengthError + ); +} + +#[test] +fn unsupported_digest() { + let t = trybuild::TestCases::new(); + t.compile_fail("src/unit_tests/compilation/small_kdf.rs"); +} + +#[test] +fn test_ikm_size() { + // Test for 16 bytes seed. + let ikm16 = [0u8; 16]; + assert!(Hkdf::::extract(None, &ikm16).is_ok()); + + // Test for 32 bytes seed. + let ikm32 = [0u8; 32]; + assert!(Hkdf::::extract(None, &ikm32).is_ok()); + + // Test for 15 bytes seed. + let ikm15 = [0u8; 15]; + assert_eq!( + Hkdf::::extract(None, &ikm15), + Err(HkdfError::InvalidSeedLengthError) + ); + + // Test for empty seed. + let ikm0 = []; + assert_eq!( + Hkdf::::extract(None, &ikm0), + Err(HkdfError::InvalidSeedLengthError) + ); +} + +// Test Vectors for sha256 from https://tools.ietf.org/html/rfc5869. +struct Test<'a> { + ikm: &'a str, + salt: &'a str, + info: &'a str, + length: usize, + prk: &'a str, + okm: &'a str, +} + +fn test_vectors_sha256<'a>() -> Vec> { + vec![ + Test { + // Test Case 1 + ikm: "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + salt: "000102030405060708090a0b0c", + info: "f0f1f2f3f4f5f6f7f8f9", + length: 42, + prk: "077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5", + okm: "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b8\ + 87185865", + }, + Test { + // Test Case 2 + ikm: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425\ + 262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b\ + 4c4d4e4f", + salt: "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848\ + 5868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aa\ + abacadaeaf", + info: "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d\ + 5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa\ + fbfcfdfeff", + length: 82, + prk: "06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244", + okm: "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7\ + 827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5\ + c1f3434f1d87", + }, + Test { + // Test Case 3 + ikm: "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + salt: "", + info: "", + length: 42, + prk: "19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04", + okm: "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4\ + b61a96c8", + }, + ] +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/mod.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/mod.rs new file mode 100644 index 000000000..ea4aebd1d --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/mod.rs @@ -0,0 +1,13 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +mod bcs_test; +mod compat_test; +mod cross_test; +mod cryptohasher; +mod ed25519_test; +mod hash_test; +mod hkdf_test; +mod multi_ed25519_test; +mod noise_test; diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/multi_ed25519_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/multi_ed25519_test.rs new file mode 100644 index 000000000..e0aafd4e1 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/multi_ed25519_test.rs @@ -0,0 +1,472 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + ed25519::{Ed25519PrivateKey, Ed25519PublicKey, ED25519_PUBLIC_KEY_LENGTH}, + multi_ed25519::{MultiEd25519PrivateKey, MultiEd25519PublicKey, MultiEd25519Signature}, + test_utils::{TestDiemCrypto, TEST_SEED}, + traits::*, + CryptoMaterialError::{ValidationError, WrongLengthError}, +}; +use core::convert::TryFrom; +use once_cell::sync::Lazy; +use rand::{rngs::StdRng, SeedableRng}; + +static MESSAGE: Lazy = Lazy::new(|| TestDiemCrypto("Test Message".to_string())); +fn message() -> &'static TestDiemCrypto { + &MESSAGE +} + +// Helper function to generate N ed25519 private keys. +fn generate_keys(n: usize) -> Vec { + let mut rng = StdRng::from_seed(TEST_SEED); + (0..n) + .map(|_| Ed25519PrivateKey::generate(&mut rng)) + .collect() +} + +// Reused assertions in our tests. +fn test_successful_public_key_serialization(original_keys: &[Ed25519PublicKey], threshold: u8) { + let n = original_keys.len(); + let public_key: MultiEd25519PublicKey = + MultiEd25519PublicKey::new(original_keys.to_vec(), threshold).unwrap(); + assert_eq!(public_key.threshold(), &threshold); + assert_eq!(public_key.public_keys().len(), n); + assert_eq!(public_key.public_keys(), &original_keys.to_vec()); + let serialized = public_key.to_bytes(); + assert_eq!(serialized.len(), n * ED25519_PUBLIC_KEY_LENGTH + 1); + let reserialized = MultiEd25519PublicKey::try_from(&serialized[..]); + assert!(reserialized.is_ok()); + assert_eq!(public_key, reserialized.unwrap()); +} + +fn test_failed_public_key_serialization( + result: std::result::Result, + expected_error: CryptoMaterialError, +) { + assert!(result.is_err()); + assert_eq!(result.err().unwrap(), expected_error); +} + +fn test_successful_signature_serialization(private_keys: &[Ed25519PrivateKey], threshold: u8) { + let multi_private_key = MultiEd25519PrivateKey::new(private_keys.to_vec(), threshold).unwrap(); + let multi_public_key = MultiEd25519PublicKey::from(&multi_private_key); + let multi_signature = multi_private_key.sign(message()); + + // Serialize then Deserialize. + let multi_signature_serialized = + MultiEd25519Signature::try_from(&multi_signature.to_bytes()[..]); + assert!(multi_signature_serialized.is_ok()); + let multi_signature_serialized_unwrapped = multi_signature_serialized.unwrap(); + assert_eq!(multi_signature, multi_signature_serialized_unwrapped); + // Ensure that the signature verifies. + assert!(multi_signature.verify(message(), &multi_public_key).is_ok()); +} + +// Test multi-sig Ed25519 public key serialization. +#[test] +fn test_multi_ed25519_public_key_serialization() { + let pub_keys_1: Vec<_> = generate_keys(1).iter().map(|x| x.public_key()).collect(); + let pub_keys_10: Vec<_> = generate_keys(10).iter().map(|x| x.public_key()).collect(); + let pub_keys_32: Vec<_> = generate_keys(32).iter().map(|x| x.public_key()).collect(); + let pub_keys_33: Vec<_> = generate_keys(33).iter().map(|x| x.public_key()).collect(); + + // Test 1-of-1 + test_successful_public_key_serialization(&pub_keys_1, 1); + // Test 1-of-10 + test_successful_public_key_serialization(&pub_keys_10, 1); + // Test 7-of-10 + test_successful_public_key_serialization(&pub_keys_10, 7); + // Test 10-of-10 + test_successful_public_key_serialization(&pub_keys_10, 10); + // Test 2-of-32 + test_successful_public_key_serialization(&pub_keys_32, 2); + // Test 32-of-32 + test_successful_public_key_serialization(&pub_keys_32, 32); + + // Test 11-of-10 (should fail). + let multi_key_11of10 = MultiEd25519PublicKey::new(pub_keys_10.clone(), 11); + test_failed_public_key_serialization(multi_key_11of10, ValidationError); + + // Test 0-of-10 (should fail). + let multi_key_0of10 = MultiEd25519PublicKey::new(pub_keys_10, 0); + test_failed_public_key_serialization(multi_key_0of10, ValidationError); + + // Test 1-of-33 (should fail). + let multi_key_1of33 = MultiEd25519PublicKey::new(pub_keys_33, 1); + test_failed_public_key_serialization(multi_key_1of33, WrongLengthError); + + // Test try_from empty bytes (should fail). + let multi_key_empty_bytes = MultiEd25519PublicKey::try_from(&[] as &[u8]); + test_failed_public_key_serialization(multi_key_empty_bytes, WrongLengthError); + + // Test try_from 1 byte (should fail). + let multi_key_1_byte = MultiEd25519PublicKey::try_from(&[0u8][..]); + test_failed_public_key_serialization(multi_key_1_byte, WrongLengthError); + + // Test try_from 31 bytes (should fail). + let multi_key_31_bytes = + MultiEd25519PublicKey::try_from(&[0u8; ED25519_PUBLIC_KEY_LENGTH - 1][..]); + test_failed_public_key_serialization(multi_key_31_bytes, WrongLengthError); + + // Test try_from 32 bytes (should fail) because we always need ED25519_PUBLIC_KEY_LENGTH * N + 1 + // bytes (thus 32N + 1). + let multi_key_32_bytes = MultiEd25519PublicKey::try_from(&[0u8; ED25519_PUBLIC_KEY_LENGTH][..]); + test_failed_public_key_serialization(multi_key_32_bytes, WrongLengthError); + + // Test try_from 34 bytes (should fail). + let multi_key_34_bytes = + MultiEd25519PublicKey::try_from(&[0u8; ED25519_PUBLIC_KEY_LENGTH + 2][..]); + test_failed_public_key_serialization(multi_key_34_bytes, WrongLengthError); + + // Test try_from 33 all zero bytes (size is fine, but it should fail due to + // validation issues). + let multi_key_33_zero_bytes = + MultiEd25519PublicKey::try_from(&[0u8; ED25519_PUBLIC_KEY_LENGTH + 1][..]); + test_failed_public_key_serialization(multi_key_33_zero_bytes, ValidationError); + + let priv_keys_10 = generate_keys(10); + let pub_keys_10: Vec<_> = priv_keys_10.iter().map(|x| x.public_key()).collect(); + + let multi_private_key_7of10 = MultiEd25519PrivateKey::new(priv_keys_10, 7).unwrap(); + let multi_public_key_7of10 = MultiEd25519PublicKey::new(pub_keys_10, 7).unwrap(); + + // Check that MultiEd25519PublicKey::from MultiEd25519PrivateKey works as expected. + let multi_public_key_7of10_from_multi_private_key = + MultiEd25519PublicKey::from(&multi_private_key_7of10); + assert_eq!( + multi_public_key_7of10_from_multi_private_key, + multi_public_key_7of10 + ); + + // Check that MultiEd25519PublicKey::from Ed25519PublicKey works as expected. + let multi_public_key_from_ed25519 = MultiEd25519PublicKey::from( + multi_public_key_7of10_from_multi_private_key.public_keys()[0].clone(), + ); + assert_eq!(multi_public_key_from_ed25519.public_keys().len(), 1); + assert_eq!( + &multi_public_key_from_ed25519.public_keys()[0], + &multi_public_key_7of10_from_multi_private_key.public_keys()[0] + ); + assert_eq!(multi_public_key_from_ed25519.threshold(), &1u8); +} + +// Test against known small subgroup public key. +#[test] +fn test_publickey_smallorder() { + // A small group point with threshold 1 (last byte). + // See EIGHT_TORSION in ed25519_test.rs for more about small group points. + let torsion_point_with_threshold_1: [u8; 33] = [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, + ]; + + let torsion_key = MultiEd25519PublicKey::try_from(&torsion_point_with_threshold_1[..]); + assert!(torsion_key.is_err()); + assert_eq!( + torsion_key.err().unwrap(), + CryptoMaterialError::SmallSubgroupError + ); +} + +// Test multi-sig Ed25519 signature serialization. +#[test] +#[allow(clippy::needless_collect)] +fn test_multi_ed25519_signature_serialization() { + let priv_keys_3 = generate_keys(3); + + // Test 1 of 3 + test_successful_signature_serialization(&priv_keys_3, 1); + // Test 2 of 3 + test_successful_signature_serialization(&priv_keys_3, 2); + // Test 3 of 3 + test_successful_signature_serialization(&priv_keys_3, 3); + + let priv_keys_32 = generate_keys(32); + // Test 1 of 32 + test_successful_signature_serialization(&priv_keys_32, 1); + // Test 32 of 32 + test_successful_signature_serialization(&priv_keys_32, 32); + + // Construct from single Ed25519Signature. + let single_signature = priv_keys_3[0].sign(message()); + let multi_signature = MultiEd25519Signature::from(single_signature.clone()); + assert_eq!(1, multi_signature.signatures().len()); + assert_eq!(multi_signature.signatures()[0], single_signature); + assert_eq!(multi_signature.bitmap(), &[0b1000_0000u8, 0u8, 0u8, 0u8]); + let multi_priv_key_1of3 = MultiEd25519PrivateKey::new(priv_keys_3.to_vec(), 1).unwrap(); + let multi_pub_key_1of3 = MultiEd25519PublicKey::from(&multi_priv_key_1of3); + assert!(multi_signature + .verify(message(), &multi_pub_key_1of3) + .is_ok()); + + // We can construct signatures from 32 single signatures. + let sigs_32 = vec![single_signature.clone(); 32]; + let indices: Vec = (0..32).collect(); + let sig32_tuple = sigs_32.into_iter().zip(indices.into_iter()).collect(); + + let multi_sig32 = MultiEd25519Signature::new(sig32_tuple); + assert!(multi_sig32.is_ok()); + let multi_sig32_unwrapped = multi_sig32.unwrap(); + assert_eq!(multi_sig32_unwrapped.bitmap(), &[ + 0b1111_1111, + 0b1111_1111, + 0b1111_1111, + 0b1111_1111 + ]); + let pub_key_32 = vec![priv_keys_3[0].public_key(); 32]; + let multi_pub_key_32 = MultiEd25519PublicKey::new(pub_key_32, 32).unwrap(); + assert!(multi_sig32_unwrapped + .verify(message(), &multi_pub_key_32) + .is_ok()); + + // Fail to construct a MultiEd25519Signature object from 33 or more single signatures. + let sigs_33 = vec![single_signature.clone(); 33]; + let indices: Vec = (0..33).collect(); + let sig33_tuple = sigs_33.into_iter().zip(indices.into_iter()).collect(); + + let multi_sig33 = MultiEd25519Signature::new(sig33_tuple); + assert!(multi_sig33.is_err()); + assert_eq!( + multi_sig33.err().unwrap(), + CryptoMaterialError::ValidationError + ); + + // Fail to construct a MultiEd25519Signature object if there are duplicated indexes. + let sigs_3 = vec![single_signature; 3]; + let indices_with_duplicate = vec![0u8, 1u8, 1u8]; + let sig3_tuple = sigs_3 + .clone() + .into_iter() + .zip(indices_with_duplicate.into_iter()) + .collect(); + + let multi_sig3 = MultiEd25519Signature::new(sig3_tuple); + assert!(multi_sig3.is_err()); + assert_eq!( + multi_sig3.err().unwrap(), + CryptoMaterialError::BitVecError("Duplicate signature index".to_string()) + ); + + // Fail to construct a MultiEd25519Signature object if an index is out of range. + let indices_with_out_of_range = vec![0u8, 33u8, 1u8]; + let sig3_tuple = sigs_3 + .into_iter() + .zip(indices_with_out_of_range.into_iter()) + .collect(); + + let multi_sig3 = MultiEd25519Signature::new(sig3_tuple); + assert!(multi_sig3.is_err()); + assert_eq!( + multi_sig3.err().unwrap(), + CryptoMaterialError::BitVecError("Signature index is out of range".to_string()) + ); +} + +// Test multi-sig Ed25519 signature verification. +#[test] +fn test_multi_ed25519_signature_verification() { + let priv_keys_10 = generate_keys(10); + let pub_keys_10: Vec<_> = priv_keys_10.iter().map(|x| x.public_key()).collect(); + + let multi_private_key_7of10 = MultiEd25519PrivateKey::new(priv_keys_10.clone(), 7).unwrap(); + let multi_public_key_7of10 = MultiEd25519PublicKey::from(&multi_private_key_7of10); + + // Verifying a 7-of-10 signature against a public key with the same threshold should pass. + let multi_signature_7of10 = multi_private_key_7of10.sign(message()); + assert_eq!(multi_signature_7of10.bitmap(), &[ + 0b1111_1110, + 0u8, + 0u8, + 0u8 + ]); + assert!(multi_signature_7of10 + .verify(message(), &multi_public_key_7of10) + .is_ok()); + + // Verifying a 7-of-10 signature against a public key with bigger threshold (i.e., 8) should fail. + let multi_public_key_8of10 = MultiEd25519PublicKey::new(pub_keys_10.clone(), 8).unwrap(); + assert!(multi_signature_7of10 + .verify(message(), &multi_public_key_8of10) + .is_err()); + + // Verifying a 7-of-10 signature against a public key with smaller threshold (i.e., 6) should pass. + let multi_public_key_6of10 = MultiEd25519PublicKey::new(pub_keys_10.clone(), 6).unwrap(); + assert!(multi_signature_7of10 + .verify(message(), &multi_public_key_6of10) + .is_ok()); + + // Verifying a 7-of-10 signature against a reordered MultiEd25519PublicKey should fail. + // To deterministically simulate reshuffling, we use a reversed vector of 10 keys. + // Note that because 10 is an even number, all of they keys will change position. + let mut pub_keys_10_reversed = pub_keys_10; + pub_keys_10_reversed.reverse(); + let multi_public_key_7of10_reversed = + MultiEd25519PublicKey::new(pub_keys_10_reversed, 7).unwrap(); + assert!(multi_signature_7of10 + .verify(message(), &multi_public_key_7of10_reversed) + .is_err()); + + let priv_keys_3 = generate_keys(3); + + let multi_private_key_1of3 = MultiEd25519PrivateKey::new(priv_keys_3.clone(), 1).unwrap(); + let multi_public_key_1of3 = MultiEd25519PublicKey::from(&multi_private_key_1of3); + + // Signing with the 2nd key must succeed. + let sig_with_2nd_key = priv_keys_3[1].sign(message()); + let multi_sig_signed_by_2nd_key = MultiEd25519Signature::new(vec![(sig_with_2nd_key, 1)]); + assert!(multi_sig_signed_by_2nd_key.is_ok()); + let multi_sig_signed_by_2nd_key_unwrapped = multi_sig_signed_by_2nd_key.unwrap(); + assert_eq!(multi_sig_signed_by_2nd_key_unwrapped.bitmap(), &[ + 0b0100_0000, + 0u8, + 0u8, + 0u8 + ]); + assert!(multi_sig_signed_by_2nd_key_unwrapped + .verify(message(), &multi_public_key_1of3) + .is_ok()); + + // Signing with the 2nd key but using wrong index will fail. + let sig_with_2nd_key = priv_keys_3[1].sign(message()); + let multi_sig_signed_by_2nd_key_wrong_index = + MultiEd25519Signature::new(vec![(sig_with_2nd_key.clone(), 2)]); + assert!(multi_sig_signed_by_2nd_key_wrong_index.is_ok()); + let failed_multi_sig_signed_by_2nd_key_wrong_index = multi_sig_signed_by_2nd_key_wrong_index + .unwrap() + .verify(message(), &multi_public_key_1of3); + assert!(failed_multi_sig_signed_by_2nd_key_wrong_index.is_err()); + + // Signing with the 2nd and 3rd keys must succeed, even if we surpass the threshold. + let sig_with_3rd_key = priv_keys_3[2].sign(message()); + let multi_sig_signed_by_2nd_and_3rd_key = MultiEd25519Signature::new(vec![ + (sig_with_2nd_key.clone(), 1), + (sig_with_3rd_key.clone(), 2), + ]); + assert!(multi_sig_signed_by_2nd_and_3rd_key.is_ok()); + let multi_sig_signed_by_2nd_and_3rd_key_unwrapped = + multi_sig_signed_by_2nd_and_3rd_key.unwrap(); + assert_eq!(multi_sig_signed_by_2nd_and_3rd_key_unwrapped.bitmap(), &[ + 0b0110_0000, + 0u8, + 0u8, + 0u8 + ]); + assert!(multi_sig_signed_by_2nd_and_3rd_key_unwrapped + .verify(message(), &multi_public_key_1of3) + .is_ok()); + + // Signing with the 2nd and 3rd keys will fail if we swap indexes. + let multi_sig_signed_by_2nd_and_3rd_key_swapped = MultiEd25519Signature::new(vec![ + (sig_with_2nd_key.clone(), 2), + (sig_with_3rd_key.clone(), 1), + ]); + let failed_multi_sig_signed_by_2nd_and_3rd_key_swapped = + multi_sig_signed_by_2nd_and_3rd_key_swapped + .unwrap() + .verify(message(), &multi_public_key_1of3); + assert!(failed_multi_sig_signed_by_2nd_and_3rd_key_swapped.is_err()); + + // Signing with the 2nd and an unrelated key. Although threshold is met, it should fail as + // we don't accept invalid signatures. + let sig_with_unrelated_key = priv_keys_10[9].sign(message()); + let multi_sig_signed_by_2nd_and_unrelated_key = MultiEd25519Signature::new(vec![ + (sig_with_2nd_key.clone(), 1), + (sig_with_unrelated_key, 2), + ]); + assert!(multi_sig_signed_by_2nd_and_unrelated_key.is_ok()); + let failed_verified_sig = multi_sig_signed_by_2nd_and_unrelated_key + .unwrap() + .verify(message(), &multi_public_key_1of3); + assert!(failed_verified_sig.is_err()); + + // Testing all combinations for 2 of 3. + let multi_private_key_2of3 = MultiEd25519PrivateKey::new(priv_keys_3.clone(), 2).unwrap(); + let multi_public_key_2of3 = MultiEd25519PublicKey::from(&multi_private_key_2of3); + + let sig_with_1st_key = priv_keys_3[0].sign(message()); + + // Signing with the 1st and 2nd keys must succeed. + let signed_by_1st_and_2nd_key = MultiEd25519Signature::new(vec![ + (sig_with_1st_key.clone(), 0), + (sig_with_2nd_key.clone(), 1), + ]); + assert!(signed_by_1st_and_2nd_key.is_ok()); + let signed_by_1st_and_2nd_key_unwrapped = signed_by_1st_and_2nd_key.unwrap(); + assert_eq!(signed_by_1st_and_2nd_key_unwrapped.bitmap(), &[ + 0b1100_0000, + 0u8, + 0u8, + 0u8 + ]); + assert!(signed_by_1st_and_2nd_key_unwrapped + .verify(message(), &multi_public_key_2of3) + .is_ok()); + + // Signing with the 1st and 3rd keys must succeed. + let signed_by_1st_and_3rd_key = MultiEd25519Signature::new(vec![ + (sig_with_1st_key.clone(), 0), + (sig_with_3rd_key.clone(), 2), + ]); + assert!(signed_by_1st_and_3rd_key.is_ok()); + let signed_by_1st_and_3rd_key_unwrapped = signed_by_1st_and_3rd_key.unwrap(); + assert_eq!(signed_by_1st_and_3rd_key_unwrapped.bitmap(), &[ + 0b1010_0000, + 0u8, + 0u8, + 0u8 + ]); + assert!(signed_by_1st_and_3rd_key_unwrapped + .verify(message(), &multi_public_key_2of3) + .is_ok()); + + // Signing with the 2nd and 3rd keys must succeed. + let signed_by_2nd_and_3rd_key = MultiEd25519Signature::new(vec![ + (sig_with_2nd_key.clone(), 1), + (sig_with_3rd_key.clone(), 2), + ]); + assert!(signed_by_2nd_and_3rd_key.is_ok()); + let signed_by_2nd_and_3rd_key_unwrapped = signed_by_2nd_and_3rd_key.unwrap(); + assert_eq!(signed_by_2nd_and_3rd_key_unwrapped.bitmap(), &[ + 0b0110_0000, + 0u8, + 0u8, + 0u8 + ]); + assert!(signed_by_2nd_and_3rd_key_unwrapped + .verify(message(), &multi_public_key_2of3) + .is_ok()); + + // Signing with the 2nd and 3rd keys must succeed. + let signed_by_all_3_keys = MultiEd25519Signature::new(vec![ + (sig_with_1st_key, 0), + (sig_with_2nd_key.clone(), 1), + (sig_with_3rd_key, 2), + ]); + assert!(signed_by_all_3_keys.is_ok()); + let signed_by_all_3_keys_unwrapped = signed_by_all_3_keys.unwrap(); + assert_eq!(signed_by_all_3_keys_unwrapped.bitmap(), &[ + 0b1110_0000, + 0u8, + 0u8, + 0u8 + ]); + assert!(signed_by_all_3_keys_unwrapped + .verify(message(), &multi_public_key_2of3) + .is_ok()); + + // Signing with the 2nd only will fail. + let signed_by_2nd_key = MultiEd25519Signature::new(vec![(sig_with_2nd_key, 1)]); + assert!(signed_by_2nd_key.is_ok()); + let signed_by_2nd_key_unwrapped = signed_by_2nd_key.unwrap(); + assert_eq!(signed_by_2nd_key_unwrapped.bitmap(), &[ + 0b0100_0000, + 0u8, + 0u8, + 0u8 + ]); + assert!(signed_by_2nd_key_unwrapped + .verify(message(), &multi_public_key_2of3) + .is_err()); +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/noise_test.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/noise_test.rs new file mode 100644 index 000000000..19b954e8d --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/unit_tests/noise_test.rs @@ -0,0 +1,533 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + noise::{handshake_init_msg_len, handshake_resp_msg_len, NoiseConfig, MAX_SIZE_NOISE_MSG}, + test_utils::TEST_SEED, + x25519, Uniform as _, +}; +use rand::SeedableRng; +use serde::*; +use std::{fs::File, io::BufReader, path::PathBuf}; + +#[test] +fn simple_handshake() { + // setup peers + let mut rng = ::rand::rngs::StdRng::from_seed(TEST_SEED); + let initiator_private = x25519::PrivateKey::generate(&mut rng); + let initiator_public = initiator_private.public_key(); + let responder_private = x25519::PrivateKey::generate(&mut rng); + let responder_public = responder_private.public_key(); + let initiator = NoiseConfig::new(initiator_private); + let responder = NoiseConfig::new(responder_private); + + // test the two APIs + for i in 0..2 { + // initiator sends first message + let prologue = b"prologue"; + let payload1 = b"payload1"; + let mut first_message = vec![0u8; handshake_init_msg_len(payload1.len())]; + let initiator_state = initiator + .initiate_connection( + &mut rng, + prologue, + responder_public, + Some(payload1), + &mut first_message, + ) + .unwrap(); + + let payload2 = b"payload2"; + let mut second_message = vec![0u8; handshake_resp_msg_len(payload2.len())]; + + // responder parses the first message and responds + let mut responder_session = if i == 0 { + let (received_payload, responder_session) = responder + .respond_to_client_and_finalize( + &mut rng, + prologue, + &first_message, + Some(payload2), + &mut second_message, + ) + .unwrap(); + let remote_static = responder_session.get_remote_static(); + assert_eq!(remote_static, initiator_public); + assert_eq!(received_payload, b"payload1"); + responder_session + } else { + let payload2 = b"payload2"; + let (remote_static, handshake_state, received_payload) = responder + .parse_client_init_message(prologue, &first_message) + .unwrap(); + assert_eq!(remote_static, initiator_public); + assert_eq!(received_payload, b"payload1"); + + responder + .respond_to_client( + &mut rng, + handshake_state, + Some(payload2), + &mut second_message, + ) + .unwrap() + }; + + // initiator parses the response + let (received_payload, mut initiator_session) = initiator + .finalize_connection(initiator_state, &second_message) + .unwrap(); + assert_eq!(received_payload, b"payload2"); + + // session usage + let mut message_sent = b"payload".to_vec(); + for i in 0..10 { + message_sent.push(i); + let mut message = message_sent.clone(); + let received_message = if i % 2 == 0 { + let auth_tag = initiator_session + .write_message_in_place(&mut message) + .expect("session should not be closed"); + message.extend_from_slice(&auth_tag); + responder_session + .read_message_in_place(&mut message) + .expect("session should not be closed") + } else { + let auth_tag = responder_session + .write_message_in_place(&mut message) + .expect("session should not be closed"); + message.extend_from_slice(&auth_tag); + initiator_session + .read_message_in_place(&mut message) + .expect("session should not be closed") + }; + assert_eq!(received_message, message_sent.as_slice()); + } + } +} + +#[test] +fn test_vectors() { + // structures needed to deserialize test vectors + #[derive(Serialize, Deserialize)] + struct TestVectors { + vectors: Vec, + } + #[derive(Serialize, Deserialize, Debug)] + struct TestVector { + protocol_name: String, + init_prologue: String, + init_static: Option, + init_ephemeral: String, + init_remote_static: Option, + resp_static: Option, + resp_ephemeral: Option, + handshake_hash: String, + messages: Vec, + } + #[derive(Serialize, Deserialize, Debug)] + struct TestMessage { + payload: String, + ciphertext: String, + } + + // EphemeralRng is used to get deterministic ephemeral keys based on test vectors + struct EphemeralRng { + ephemeral: Vec, + } + impl rand::RngCore for EphemeralRng { + fn next_u32(&mut self) -> u32 { + unreachable!() + } + + fn next_u64(&mut self) -> u64 { + unreachable!() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + dest.copy_from_slice(&self.ephemeral); + } + + fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), rand::Error> { + unreachable!() + } + } + impl rand::CryptoRng for EphemeralRng {} + + // test vectors are taken from the cacophony library + let mut test_vectors_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + test_vectors_path.push("test_vectors"); + test_vectors_path.push("noise_cacophony.txt"); + let test_vectors_path = test_vectors_path.to_str().unwrap(); + let test_vectors_file = File::open(test_vectors_path).expect("missing noise test vectors"); + let test_vectors: TestVectors = + serde_json::from_reader(BufReader::new(test_vectors_file)).unwrap(); + + // only go through Noise_IK_25519_AESGCM_SHA256 test vectors (don't exist for SHA-3) + let test_vector = test_vectors + .vectors + .iter() + .find(|vector| vector.protocol_name == "Noise_IK_25519_AESGCM_SHA256") + .expect("test vector for Noise_IK_25519_AESGCM_SHA256 should be in cacophony test vectors"); + + // initiate peers with test vector + use crate::traits::ValidCryptoMaterialStringExt; + let initiator_private = + x25519::PrivateKey::from_encoded_string(test_vector.init_static.as_ref().unwrap()).unwrap(); + let initiator_public = initiator_private.public_key(); + let responder_private = + x25519::PrivateKey::from_encoded_string(test_vector.resp_static.as_ref().unwrap()).unwrap(); + let responder_public = responder_private.public_key(); + + let initiator = NoiseConfig::new(initiator_private); + let responder = NoiseConfig::new(responder_private); + + // test the two APIs + for i in 0..2 { + // assert public keys + let init_remote_static = + hex::decode(test_vector.init_remote_static.as_ref().unwrap()).unwrap(); + assert_eq!(responder_public.as_slice(), init_remote_static.as_slice()); + + // go through handshake test messages + let prologue = hex::decode(&test_vector.init_prologue).unwrap(); + let mut messages = test_vector.messages.iter(); + + // first handshake message + let message = messages.next().unwrap(); + let payload1 = hex::decode(&message.payload).unwrap(); + let expected_ciphertext = hex::decode(&message.ciphertext).unwrap(); + let init_ephemeral = hex::decode(&test_vector.init_ephemeral).unwrap(); + let mut rng = EphemeralRng { + ephemeral: init_ephemeral, + }; + let mut first_message = vec![0u8; handshake_init_msg_len(payload1.len())]; + let initiator_state = initiator + .initiate_connection( + &mut rng, + &prologue, + responder_public, + Some(&payload1), + &mut first_message, + ) + .unwrap(); + assert_eq!(first_message, expected_ciphertext); + + // second handshake message + let message = messages.next().unwrap(); + let payload2 = hex::decode(&message.payload).unwrap(); + let expected_ciphertext = hex::decode(&message.ciphertext).unwrap(); + + // responder part + let resp_ephemeral = hex::decode(test_vector.resp_ephemeral.as_ref().unwrap()).unwrap(); + let mut rng = EphemeralRng { + ephemeral: resp_ephemeral, + }; + let mut second_message = vec![0u8; handshake_resp_msg_len(payload2.len())]; + + let mut responder_session = if i == 0 { + let (received_payload, responder_session) = responder + .respond_to_client_and_finalize( + &mut rng, + &prologue, + &first_message, + Some(&payload2), + &mut second_message, + ) + .unwrap(); + assert_eq!(payload1, received_payload); + responder_session + } else { + let (remote_static, handshake_state, received_payload) = responder + .parse_client_init_message(&prologue, &first_message) + .unwrap(); + assert_eq!(remote_static, initiator_public); + assert_eq!(payload1, received_payload); + + responder + .respond_to_client( + &mut rng, + handshake_state, + Some(&payload2), + &mut second_message, + ) + .unwrap() + }; + + let remote_static = responder_session.get_remote_static(); + assert_eq!(second_message, expected_ciphertext); + assert_eq!(remote_static, initiator_public); + + // initiator part + let (received_payload, mut initiator_session) = initiator + .finalize_connection(initiator_state, &second_message) + .unwrap(); + assert_eq!(payload2, received_payload); + + // post-handshake messages + let mut client_turn = true; + for message in messages { + // decode + let payload = hex::decode(&message.payload).unwrap(); + let expected_ciphertext = hex::decode(&message.ciphertext).unwrap(); + + // initiator and responder takes turn to send messages + let mut message = payload.clone(); + if client_turn { + let auth_tag = initiator_session + .write_message_in_place(&mut message) + .expect("session should not be closed"); + message.extend_from_slice(&auth_tag); + assert_eq!(message, expected_ciphertext); + + let received_payload = responder_session + .read_message_in_place(&mut message) + .expect("session should not be closed"); + assert_eq!(payload, received_payload); + } else { + let auth_tag = responder_session + .write_message_in_place(&mut message) + .expect("session should not be closed"); + message.extend_from_slice(&auth_tag); + assert_eq!(message, expected_ciphertext); + + let received_payload = initiator_session + .read_message_in_place(&mut message) + .expect("session should not be closed"); + assert_eq!(payload, received_payload); + } + + // swap sender + client_turn = !client_turn; + } + } +} + +// Negative tests +// -------------- +// +// things that should fail during the handshake: +// - buffer to write is too small (should fail) +// - message received is too small (should fail) +// - message received is too big (should fail) +// - message received is larger than max noise size (should fail) +// - payload to write is larger than max noise size (should fail) +// +// things that should work during the handshake: +// - buffer to write is too big +// + +#[test] +fn wrong_buffer_sizes() { + // setup peers + let mut rng = ::rand::rngs::StdRng::from_seed(TEST_SEED); + let initiator_private = x25519::PrivateKey::generate(&mut rng); + let responder_private = x25519::PrivateKey::generate(&mut rng); + let responder_public = responder_private.public_key(); + let initiator = NoiseConfig::new(initiator_private); + let responder = NoiseConfig::new(responder_private); + + // test the two APIs + for i in 0..2 { + // initiator sends first message with buffer too small (should fail) + let payload = b"payload"; + let mut first_message_bad = vec![0u8; handshake_init_msg_len(payload.len()) - 1]; + let res = initiator.initiate_connection( + &mut rng, + b"", + responder_public, + Some(payload), + &mut first_message_bad, + ); + + assert!(matches!(res, Err(_))); + + // try again with payload too large (should fail) + let mut large_buffer = vec![0u8; MAX_SIZE_NOISE_MSG + 3]; + let payload_too_large = vec![1u8; MAX_SIZE_NOISE_MSG - handshake_init_msg_len(0) + 1]; + let res = initiator.initiate_connection( + &mut rng, + b"", + responder_public, + Some(&payload_too_large), + &mut large_buffer, + ); + + assert!(matches!(res, Err(_))); + + // try again with buffer too large (should work) + let mut first_message_good = vec![0u8; handshake_init_msg_len(payload.len()) + 1]; + let initiator_state = initiator + .initiate_connection( + &mut rng, + b"", + responder_public, + Some(payload), + &mut first_message_good, + ) + .unwrap(); + + // responder parses the first message and responds + let mut second_message_small = vec![0u8; handshake_resp_msg_len(payload.len()) - 1]; + let mut second_message_large = vec![0u8; handshake_resp_msg_len(payload.len()) + 1]; + + let (mut responder_session, second_message_large) = if i == 0 { + // with buffer too small (shouldn't work) + let res = responder.respond_to_client_and_finalize( + &mut rng, + b"", + &first_message_good[..first_message_good.len() - 1], + Some(payload), + &mut second_message_small, + ); + + assert!(matches!(res, Err(_))); + + // with first message too large (shouldn't work) + let res = responder.respond_to_client_and_finalize( + &mut rng, + b"", + &first_message_good, + Some(payload), + &mut second_message_large, + ); + + assert!(matches!(res, Err(_))); + + // with incorrect prologue (should fail) + let res = responder.respond_to_client_and_finalize( + &mut rng, + b"incorrect prologue", + &first_message_good[..first_message_good.len() - 1], + Some(payload), + &mut second_message_large, + ); + + assert!(matches!(res, Err(_))); + + // with payload too large (should fail) + let mut large_buffer = vec![0u8; MAX_SIZE_NOISE_MSG + 3]; + let payload_too_large = vec![1u8; MAX_SIZE_NOISE_MSG - handshake_resp_msg_len(0) + 1]; + let res = responder.respond_to_client_and_finalize( + &mut rng, + b"", + &first_message_good[..first_message_good.len() - 1], + Some(&payload_too_large), + &mut large_buffer, + ); + + assert!(matches!(res, Err(_))); + + // with correct first message and buffer too large (should work) + let (_, responder_session) = responder + .respond_to_client_and_finalize( + &mut rng, + b"", + &first_message_good[..first_message_good.len() - 1], + Some(payload), + &mut second_message_large, + ) + .unwrap(); + + (responder_session, second_message_large) + } else { + // with first message too large + let res = responder.parse_client_init_message(b"", &first_message_good); + + assert!(matches!(res, Err(_))); + + // with first message too small + let res = responder.parse_client_init_message( + b"", + &first_message_good[..first_message_good.len() - 2], + ); + + assert!(matches!(res, Err(_))); + + // with wrong prologue + let res = responder.parse_client_init_message( + b"incorrect prologue", + &first_message_good[..first_message_good.len() - 1], + ); + + assert!(matches!(res, Err(_))); + + // with first message of correct length + let (_, handshake_state, _) = responder + .parse_client_init_message(b"", &first_message_good[..first_message_good.len() - 1]) + .unwrap(); + + // write to buffer to small (should fail) + let res = responder.respond_to_client( + &mut rng, + handshake_state.clone(), + Some(payload), + &mut second_message_small, + ); + + assert!(matches!(res, Err(_))); + + // with payload too large (should fail) + let mut large_buffer = vec![0u8; MAX_SIZE_NOISE_MSG + 3]; + let payload_too_large = vec![1u8; MAX_SIZE_NOISE_MSG - handshake_resp_msg_len(0) + 1]; + let res = responder.respond_to_client( + &mut rng, + handshake_state.clone(), + Some(&payload_too_large), + &mut large_buffer, + ); + + assert!(matches!(res, Err(_))); + + // write to buffer too big (should work) + let responder_session = responder + .respond_to_client( + &mut rng, + handshake_state, + Some(payload), + &mut second_message_large, + ) + .unwrap(); + + (responder_session, second_message_large) + }; + + // initiator parses the response too large (should fail) + let res = initiator.finalize_connection(initiator_state.clone(), &second_message_large); + + assert!(matches!(res, Err(_))); + + // initiator parses the response too small (should fail) + let res = initiator.finalize_connection( + initiator_state.clone(), + &second_message_large[..second_message_large.len() - 2], + ); + + assert!(matches!(res, Err(_))); + + // initiator parses response of correct size + let (_, mut initiator_session) = initiator + .finalize_connection( + initiator_state.clone(), + &second_message_large[..second_message_large.len() - 1], + ) + .unwrap(); + + // session usage + let mut message = b"".to_vec(); + + let auth_tag = initiator_session + .write_message_in_place(&mut message) + .expect("should work"); + + // message too short to have auth tag + let res = responder_session.read_message_in_place(&mut message); + assert!(matches!(res, Err(_))); + + // session should be unusable now + message.extend_from_slice(&auth_tag); + let res = responder_session.read_message_in_place(&mut message); + assert!(matches!(res, Err(_))); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/validatable.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/validatable.rs new file mode 100644 index 000000000..76d987b70 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/validatable.rs @@ -0,0 +1,295 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module provides the `Validate` trait and `Validatable` type in order to aid in deferred +//! validation. + +use anyhow::Result; +use once_cell::sync::OnceCell; +use serde::{Deserialize, Serialize}; +use std::{convert::TryFrom, hash::Hash}; + +/// The `Validate` trait is used in tandem with the `Validatable` type in order to provide deferred +/// validation for types. +/// +/// ## Trait Contract +/// +/// Any type `V` which implement this trait must adhere to the following contract: +/// +/// * `V` and `V::Unvalidated` are byte-for-byte equivalent. +/// * `V` and `V::Unvalidated` have equivalent `Hash` implementations. +/// * `V` and `V::Unvalidated` must have equivalent `Serialize` and `Deserialize` implementation. +/// This means that `V` and `V:Unvalidated` have equivalent serialized formats and that you can +/// deserialize a `V::Unvalidated` from a `V` that was previously serialized. +pub trait Validate: Sized { + /// The unvalidated form of some type `V` + type Unvalidated; + + /// Attempt to validate a `V::Unvalidated` and returning a validated `V` on success + fn validate(unvalidated: &Self::Unvalidated) -> Result; + + /// Return the unvalidated form of type `V` + fn to_unvalidated(&self) -> Self::Unvalidated; +} + +/// Used in connection with the `Validate` trait to be able to represent types which can benefit +/// from deferred validation as a performance optimization. +#[derive(Clone, Debug)] +pub struct Validatable { + unvalidated: V::Unvalidated, + maybe_valid: OnceCell, +} + +impl Validatable { + /// Create a new `Validatable` from a valid type + pub fn new_valid(valid: V) -> Self { + let unvalidated = valid.to_unvalidated(); + + let maybe_valid = OnceCell::new(); + maybe_valid.set(valid).unwrap_or_else(|_| unreachable!()); + + Self { + unvalidated, + maybe_valid, + } + } + + /// Create a new `Validatable` from an unvalidated type + pub fn new_unvalidated(unvalidated: V::Unvalidated) -> Self { + Self { + unvalidated, + maybe_valid: OnceCell::new(), + } + } + + /// Return a reference to the unvalidated form `V::Unvalidated` + pub fn unvalidated(&self) -> &V::Unvalidated { + &self.unvalidated + } + + /// Try to validate the unvalidated form returning `Some(&V)` on success and `None` on failure. + pub fn valid(&self) -> Option<&V> { + self.validate().ok() + } + + // TODO maybe optimize to only try once and keep track when we fail + /// Attempt to validate `V::Unvalidated` and return a reference to a valid `V` + pub fn validate(&self) -> Result<&V> { + self.maybe_valid + .get_or_try_init(|| V::validate(&self.unvalidated)) + } +} + +impl Serialize for Validatable +where + V: Validate + Serialize, + V::Unvalidated: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.unvalidated.serialize(serializer) + } +} + +impl<'de, V> Deserialize<'de> for Validatable +where + V: Validate, + V::Unvalidated: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let unvalidated = ::deserialize(deserializer)?; + Ok(Self::new_unvalidated(unvalidated)) + } +} + +impl PartialEq for Validatable +where + V: Validate, + V::Unvalidated: PartialEq, +{ + fn eq(&self, other: &Self) -> bool { + self.unvalidated == other.unvalidated + } +} + +impl Eq for Validatable +where + V: Validate, + V::Unvalidated: Eq, +{ +} + +impl Hash for Validatable +where + V: Validate, + V::Unvalidated: Hash, +{ + fn hash(&self, state: &mut H) { + self.unvalidated.hash(state); + } +} + +// +// Implement for Ed25519 +// + +use crate::ed25519::{Ed25519PublicKey, ED25519_PUBLIC_KEY_LENGTH}; + +/// An unvalidated `Ed25519PublicKey` +#[derive(Debug, Clone, Eq)] +pub struct UnvalidatedEd25519PublicKey([u8; ED25519_PUBLIC_KEY_LENGTH]); + +impl UnvalidatedEd25519PublicKey { + /// Return key as bytes + pub fn to_bytes(&self) -> [u8; ED25519_PUBLIC_KEY_LENGTH] { + self.0 + } +} + +impl Serialize for UnvalidatedEd25519PublicKey { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + let encoded = ::hex::encode(self.0); + serializer.serialize_str(&encoded) + } else { + // See comment in deserialize_key. + serializer.serialize_newtype_struct( + "Ed25519PublicKey", + serde_bytes::Bytes::new(self.0.as_ref()), + ) + } + } +} + +impl<'de> Deserialize<'de> for UnvalidatedEd25519PublicKey { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + + if deserializer.is_human_readable() { + let encoded_key = ::deserialize(deserializer)?; + let bytes_out = ::hex::decode(encoded_key).map_err(D::Error::custom)?; + <[u8; ED25519_PUBLIC_KEY_LENGTH]>::try_from(bytes_out.as_ref()) + .map(UnvalidatedEd25519PublicKey) + .map_err(D::Error::custom) + } else { + // In order to preserve the Serde data model and help analysis tools, + // make sure to wrap our value in a container with the same name + // as the original type. + #[derive(Deserialize)] + #[serde(rename = "Ed25519PublicKey")] + struct Value<'a>(&'a [u8]); + + let value = Value::deserialize(deserializer)?; + <[u8; ED25519_PUBLIC_KEY_LENGTH]>::try_from(value.0) + .map(UnvalidatedEd25519PublicKey) + .map_err(D::Error::custom) + } + } +} + +impl Hash for UnvalidatedEd25519PublicKey { + fn hash(&self, state: &mut H) { + state.write(&self.0) + } +} + +impl PartialEq for UnvalidatedEd25519PublicKey { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl Validate for Ed25519PublicKey { + type Unvalidated = UnvalidatedEd25519PublicKey; + + fn validate(unvalidated: &Self::Unvalidated) -> Result { + Self::try_from(unvalidated.0.as_ref()).map_err(Into::into) + } + + fn to_unvalidated(&self) -> Self::Unvalidated { + UnvalidatedEd25519PublicKey(self.to_bytes()) + } +} + +#[cfg(test)] +mod test { + use crate::{ + ed25519::{Ed25519PrivateKey, Ed25519PublicKey}, + test_utils::uniform_keypair_strategy, + validatable::{UnvalidatedEd25519PublicKey, Validate}, + }; + use proptest::prelude::*; + use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + }; + + proptest! { + #[test] + fn unvalidated_ed25519_public_key_equivalence( + keypair in uniform_keypair_strategy::() + ) { + let valid = keypair.public_key; + let unvalidated = valid.to_unvalidated(); + + prop_assert_eq!(&unvalidated, &UnvalidatedEd25519PublicKey(valid.to_bytes())); + prop_assert_eq!(&valid, &Ed25519PublicKey::validate(&unvalidated).unwrap()); + + // Ensure Serialize and Deserialize are implemented the same + + // BCS - A non-human-readable format + { + let serialized_valid = bcs::to_bytes(&valid).unwrap(); + let serialized_unvalidated = bcs::to_bytes(&unvalidated).unwrap(); + prop_assert_eq!(&serialized_valid, &serialized_unvalidated); + + let deserialized_valid_from_unvalidated: Ed25519PublicKey = bcs::from_bytes(&serialized_unvalidated).unwrap(); + let deserialized_unvalidated_from_valid: UnvalidatedEd25519PublicKey = bcs::from_bytes(&serialized_valid).unwrap(); + + prop_assert_eq!(&valid, &deserialized_valid_from_unvalidated); + prop_assert_eq!(&unvalidated, &deserialized_unvalidated_from_valid); + } + + // JSON A human-readable format + { + let serialized_valid = serde_json::to_string(&valid).unwrap(); + let serialized_unvalidated = serde_json::to_string(&unvalidated).unwrap(); + prop_assert_eq!(&serialized_valid, &serialized_unvalidated); + + let deserialized_valid_from_unvalidated: Ed25519PublicKey = serde_json::from_str(&serialized_unvalidated).unwrap(); + let deserialized_unvalidated_from_valid: UnvalidatedEd25519PublicKey = serde_json::from_str(&serialized_valid).unwrap(); + + prop_assert_eq!(&valid, &deserialized_valid_from_unvalidated); + prop_assert_eq!(&unvalidated, &deserialized_unvalidated_from_valid); + } + + + // Ensure Hash is implemented the same + let valid_hash = { + let mut hasher = DefaultHasher::new(); + valid.hash(&mut hasher); + hasher.finish() + }; + + let unvalidated_hash = { + let mut hasher = DefaultHasher::new(); + unvalidated.hash(&mut hasher); + hasher.finish() + }; + + prop_assert_eq!(valid_hash, unvalidated_hash); + } + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/x25519.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/x25519.rs new file mode 100644 index 000000000..ebe847232 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/crypto/src/x25519.rs @@ -0,0 +1,269 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! An abstraction of x25519 elliptic curve keys required for +//! [Diffie-Hellman key exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) +//! in the Diem project. +//! Ideally, only `x25519::PrivateKey` and `x25519::PublicKey` should be used throughout the +//! codebase, until the bytes are actually used in cryptographic operations. +//! +//! # Examples +//! +//! ``` +//! use diem_crypto::{x25519, Uniform, test_utils::TEST_SEED}; +//! use rand::{rngs::StdRng, SeedableRng}; +//! +//! // Derive an X25519 private key for testing. +//! let mut rng: StdRng = SeedableRng::from_seed(TEST_SEED); +//! let private_key = x25519::PrivateKey::generate(&mut rng); +//! let public_key = private_key.public_key(); +//! +//! // Deserialize an hexadecimal private or public key +//! use diem_crypto::traits::ValidCryptoMaterialStringExt; +//! # fn main() -> Result<(), diem_crypto::traits::CryptoMaterialError> { +//! let private_key = "404acc8ec6a0f18df7359a6ee7823f19dd95616b10fed8bdb0de030e891b945a"; +//! let private_key = x25519::PrivateKey::from_encoded_string(&private_key)?; +//! let public_key = "080e287879c918794170e258bfaddd75acac5b3e350419044655e4983a487120"; +//! let public_key = x25519::PublicKey::from_encoded_string(&public_key)?; +//! # Ok(()) +//! # } +//! ``` +//! + +use crate::{ + traits::{self, CryptoMaterialError, ValidCryptoMaterial, ValidCryptoMaterialStringExt}, + x25519, +}; +use diem_crypto_derive::{DeserializeKey, SerializeKey, SilentDebug, SilentDisplay}; +#[cfg(any(test, feature = "fuzzing"))] +use proptest_derive::Arbitrary; +use rand::{CryptoRng, RngCore}; +use std::convert::{TryFrom, TryInto}; +// +// Underlying Implementation +// ========================= +// +// We re-export the dalek-x25519 library, +// This makes it easier to uniformalize build dalek-x25519 in diem-core. +// +pub use x25519_dalek; + +// +// Main types and constants +// ======================== +// + +/// Size of a X25519 private key +pub const PRIVATE_KEY_SIZE: usize = 32; + +/// Size of a X25519 public key +pub const PUBLIC_KEY_SIZE: usize = 32; + +/// Size of a X25519 shared secret +pub const SHARED_SECRET_SIZE: usize = 32; + +/// This type should be used to deserialize a received private key +#[derive(DeserializeKey, SilentDisplay, SilentDebug, SerializeKey)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(Clone))] +pub struct PrivateKey(x25519_dalek::StaticSecret); + +/// This type should be used to deserialize a received public key +#[derive( + Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, SerializeKey, DeserializeKey, +)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] +pub struct PublicKey([u8; PUBLIC_KEY_SIZE]); + +// +// Handy implementations +// ===================== +// + +impl PrivateKey { + /// Obtain the public key part of a private key + pub fn public_key(&self) -> PublicKey { + let public_key: x25519_dalek::PublicKey = (&self.0).into(); + PublicKey(public_key.as_bytes().to_owned()) + } + + /// To perform a key exchange with another public key + pub fn diffie_hellman(&self, remote_public_key: &PublicKey) -> [u8; SHARED_SECRET_SIZE] { + let remote_public_key = x25519_dalek::PublicKey::from(remote_public_key.0); + let shared_secret = self.0.diffie_hellman(&remote_public_key); + shared_secret.as_bytes().to_owned() + } + + /// Deserialize an X25119 PrivateKey given the sha512 pre-image of a hash + /// whose least significant half is a canonical X25519 scalar, following + /// the XEdDSA approach. + /// + /// This will FAIL if the passed-in byte representation converts to a + /// non-canonical scalar in the X25519 sense (and thus cannot correspond to + /// a X25519 valid key without bit-mangling). + /// + /// This is meant to compensate for the poor key storage capabilities of some + /// key management solutions, and NOT to promote double usage of keys under + /// several schemes, which would lead to BAD vulnerabilities. + pub fn from_ed25519_private_bytes(private_slice: &[u8]) -> Result { + let ed25519_secretkey = ed25519_dalek::SecretKey::from_bytes(private_slice) + .map_err(|_| CryptoMaterialError::DeserializationError)?; + let expanded_key = ed25519_dalek::ExpandedSecretKey::from(&ed25519_secretkey); + + let mut expanded_keypart = [0u8; 32]; + expanded_keypart.copy_from_slice(&expanded_key.to_bytes()[..32]); + let potential_x25519 = x25519::PrivateKey::from(expanded_keypart); + + // This checks for x25519 clamping & reduction, which is an RFC requirement + if potential_x25519.to_bytes()[..] != expanded_key.to_bytes()[..32] { + Err(CryptoMaterialError::DeserializationError) + } else { + Ok(potential_x25519) + } + } +} + +impl PublicKey { + /// Obtain a slice reference to the underlying bytearray + pub fn as_slice(&self) -> &[u8] { + &self.0 + } + + /// Deserialize an X25119 PublicKey from its representation as an + /// Ed25519PublicKey, following the XEdDSA approach. This is meant to + /// compensate for the poor key storage capabilities of key management + /// solutions, and NOT to promote double usage of keys under several + /// schemes, which would lead to BAD vulnerabilities. + pub fn from_ed25519_public_bytes(ed25519_bytes: &[u8]) -> Result { + if ed25519_bytes.len() != 32 { + return Err(CryptoMaterialError::DeserializationError); + } + let ed_point = curve25519_dalek::edwards::CompressedEdwardsY::from_slice(ed25519_bytes) + .decompress() + .ok_or(CryptoMaterialError::DeserializationError)?; + + Ok(x25519::PublicKey::from(ed_point.to_montgomery().to_bytes())) + } +} + +// +// Traits implementations +// ====================== +// + +// private key part + +impl std::convert::From<[u8; PRIVATE_KEY_SIZE]> for PrivateKey { + fn from(private_key_bytes: [u8; PRIVATE_KEY_SIZE]) -> Self { + Self(x25519_dalek::StaticSecret::from(private_key_bytes)) + } +} + +impl std::convert::TryFrom<&[u8]> for PrivateKey { + type Error = traits::CryptoMaterialError; + + fn try_from(private_key_bytes: &[u8]) -> Result { + let private_key_bytes: [u8; PRIVATE_KEY_SIZE] = private_key_bytes + .try_into() + .map_err(|_| traits::CryptoMaterialError::DeserializationError)?; + Ok(Self(x25519_dalek::StaticSecret::from(private_key_bytes))) + } +} + +impl traits::PrivateKey for PrivateKey { + type PublicKeyMaterial = PublicKey; +} + +impl traits::Uniform for PrivateKey { + fn generate(rng: &mut R) -> Self + where + R: RngCore + CryptoRng, + { + Self(x25519_dalek::StaticSecret::new(rng)) + } +} + +// TODO: should this be gated under test flag? (mimoo) +impl traits::ValidCryptoMaterial for PrivateKey { + fn to_bytes(&self) -> Vec { + self.0.to_bytes().to_vec() + } +} + +#[cfg(any(test, feature = "fuzzing"))] +impl PartialEq for PrivateKey { + fn eq(&self, other: &Self) -> bool { + self.to_bytes() == other.to_bytes() + } +} + +#[cfg(any(test, feature = "fuzzing"))] +impl proptest::arbitrary::Arbitrary for PrivateKey { + type Parameters = (); + type Strategy = proptest::strategy::BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + use proptest::strategy::Strategy as _; + proptest::arbitrary::any::<[u8; 32]>() + .prop_map(PrivateKey::from) + .boxed() + } +} + +// public key part + +impl From<&PrivateKey> for PublicKey { + fn from(private_key: &PrivateKey) -> Self { + private_key.public_key() + } +} + +impl std::convert::From<[u8; PUBLIC_KEY_SIZE]> for PublicKey { + fn from(public_key_bytes: [u8; PUBLIC_KEY_SIZE]) -> Self { + Self(public_key_bytes) + } +} + +impl std::convert::TryFrom<&[u8]> for PublicKey { + type Error = traits::CryptoMaterialError; + + fn try_from(public_key_bytes: &[u8]) -> Result { + let public_key_bytes: [u8; PUBLIC_KEY_SIZE] = public_key_bytes + .try_into() + .map_err(|_| traits::CryptoMaterialError::WrongLengthError)?; + Ok(Self(public_key_bytes)) + } +} + +impl traits::PublicKey for PublicKey { + type PrivateKeyMaterial = PrivateKey; +} + +impl traits::ValidCryptoMaterial for PublicKey { + fn to_bytes(&self) -> Vec { + self.0.to_vec() + } +} + +impl std::fmt::Display for PublicKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", hex::encode(self.0)) + } +} + +impl std::fmt::Debug for PublicKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "x25519::PublicKey({})", self) + } +} + +#[cfg(any(test, feature = "fuzzing"))] +use crate::test_utils::{self, KeyPair}; +#[cfg(any(test, feature = "fuzzing"))] +use proptest::prelude::*; + +/// Produces a uniformly random ed25519 keypair from a seed +#[cfg(any(test, feature = "fuzzing"))] +pub fn keypair_strategy() -> impl Strategy> { + test_utils::uniform_keypair_strategy::() +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/natives/Cargo.toml b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/Cargo.toml new file mode 100644 index 000000000..84aa3fba8 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "diem-framework-natives" +version = "0.0.0" +authors = ["Diem Association "] +publish = false +edition = "2021" +license = "Apache-2.0" + +[dependencies] +move-binary-format = { path = "../../../../../move-binary-format" } +move-core-types = { path = "../../../../../move-core-types" } +move-vm-runtime = { path = "../../../../../move-vm/runtime" } +move-vm-types = { path = "../../../../../move-vm/types" } + +diem-crypto = { path = "../crypto" } + +smallvec = "1.6.1" diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/account.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/account.rs new file mode 100644 index 000000000..971da950b --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/account.rs @@ -0,0 +1,39 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::errors::PartialVMResult; +use move_core_types::account_address::AccountAddress; +use move_vm_runtime::native_functions::NativeContext; +use move_vm_types::{ + loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value, +}; +use smallvec::smallvec; +use std::collections::VecDeque; + +pub fn native_create_signer( + _context: &mut NativeContext, + ty_args: Vec, + mut arguments: VecDeque, +) -> PartialVMResult { + debug_assert!(ty_args.is_empty()); + debug_assert!(arguments.len() == 1); + + let address = pop_arg!(arguments, AccountAddress); + Ok(NativeResult::ok(25.into(), smallvec![Value::signer( + address + )])) +} + +/// NOTE: this function will be deprecated after the Diem v3 release, but must +/// remain for replaying old transactions +pub fn native_destroy_signer( + _context: &mut NativeContext, + ty_args: Vec, + arguments: VecDeque, +) -> PartialVMResult { + debug_assert!(ty_args.is_empty()); + debug_assert!(arguments.len() == 1); + + Ok(NativeResult::ok(213.into(), smallvec![])) +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/lib.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/lib.rs new file mode 100644 index 000000000..d8d48c5b4 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/lib.rs @@ -0,0 +1,45 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pub mod account; +pub mod signature; + +use move_core_types::account_address::AccountAddress; +use move_vm_runtime::native_functions::{ + make_table_from_iter, NativeFunction, NativeFunctionTable, +}; +use std::sync::Arc; + +pub fn all_natives(diem_framework_addr: AccountAddress) -> NativeFunctionTable { + let natives: [(&str, &str, NativeFunction); 5] = [ + // TODO: Remove once/if DPN is moved over to use the core framework + ( + "DiemAccount", + "create_signer", + Arc::new(account::native_create_signer), + ), + ( + "DiemAccount", + "destroy_signer", + Arc::new(account::native_destroy_signer), + ), + ( + "Signature", + "ed25519_validate_pubkey", + Arc::new(signature::native_ed25519_publickey_validation), + ), + ( + "Signature", + "ed25519_verify", + Arc::new(signature::native_ed25519_signature_verification), + ), + ( + "Account", + "create_signer", + Arc::new(account::native_create_signer), + ), + ]; + + make_table_from_iter(diem_framework_addr, natives) +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/signature.rs b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/signature.rs new file mode 100644 index 000000000..cab54afaa --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/crates/natives/src/signature.rs @@ -0,0 +1,62 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use diem_crypto::{ed25519, traits::*}; +use move_binary_format::errors::PartialVMResult; +use move_vm_runtime::native_functions::NativeContext; +use move_vm_types::{ + loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value, +}; +use smallvec::smallvec; +use std::{collections::VecDeque, convert::TryFrom}; + +pub fn native_ed25519_publickey_validation( + _context: &mut NativeContext, + _ty_args: Vec, + mut arguments: VecDeque, +) -> PartialVMResult { + debug_assert!(_ty_args.is_empty()); + debug_assert!(arguments.len() == 1); + + let key_bytes = pop_arg!(arguments, Vec); + + let cost = 26 * usize::max(key_bytes.len(), 1) as u64; + + // This deserialization performs point-on-curve and small subgroup checks + let valid = ed25519::Ed25519PublicKey::try_from(&key_bytes[..]).is_ok(); + Ok(NativeResult::ok(cost.into(), smallvec![Value::bool(valid)])) +} + +pub fn native_ed25519_signature_verification( + _context: &mut NativeContext, + _ty_args: Vec, + mut arguments: VecDeque, +) -> PartialVMResult { + debug_assert!(_ty_args.is_empty()); + debug_assert!(arguments.len() == 3); + + let msg = pop_arg!(arguments, Vec); + let pubkey = pop_arg!(arguments, Vec); + let signature = pop_arg!(arguments, Vec); + + let cost = 62 * usize::max(msg.len(), 1) as u64; + + let sig = match ed25519::Ed25519Signature::try_from(signature.as_slice()) { + Ok(sig) => sig, + Err(_) => { + return Ok(NativeResult::ok(cost.into(), smallvec![Value::bool(false)])); + }, + }; + let pk = match ed25519::Ed25519PublicKey::try_from(pubkey.as_slice()) { + Ok(pk) => pk, + Err(_) => { + return Ok(NativeResult::ok(cost.into(), smallvec![Value::bool(false)])); + }, + }; + + let verify_result = sig.verify_arbitrary_msg(msg.as_slice(), &pk).is_ok(); + Ok(NativeResult::ok(cost.into(), smallvec![Value::bool( + verify_result + )])) +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/Move.toml b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/Move.toml new file mode 100644 index 000000000..406314080 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/Move.toml @@ -0,0 +1,15 @@ +[package] +name = "DPNFramework" +version = "1.5.0" + +[addresses] +std = "0x1" +DiemFramework = "0x1" +DiemRoot = "0xA550C18" +TreasuryCompliance = "0xB1E55ED" +CurrencyInfo = "0xA550C18" +VMReserved = "0x0" + +[dependencies] +MoveStdlib = { local = "../../../../../move-stdlib" } +MoveNursery = { local = "../../../../../move-stdlib/nursery" } diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountAdministrationScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountAdministrationScripts.move new file mode 100644 index 000000000..1cf3cf942 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountAdministrationScripts.move @@ -0,0 +1,688 @@ +/// This module holds transactions that can be used to administer accounts in the Diem Framework. +module DiemFramework::AccountAdministrationScripts { + use DiemFramework::DiemAccount; + use DiemFramework::RecoveryAddress; + use DiemFramework::SharedEd25519PublicKey; + use DiemFramework::SlidingNonce; + use DiemFramework::DualAttestation; + use DiemFramework::VASPDomain; + use DiemFramework::CRSN; + + /// # Summary + /// Adds a zero `Currency` balance to the sending `account`. This will enable `account` to + /// send, receive, and hold `Diem::Diem` coins. This transaction can be + /// successfully sent by any account that is allowed to hold balances + /// (e.g., VASP, Designated Dealer). + /// + /// # Technical Description + /// After the successful execution of this transaction the sending account will have a + /// `DiemAccount::Balance` resource with zero balance published under it. Only + /// accounts that can hold balances can send this transaction, the sending account cannot + /// already have a `DiemAccount::Balance` published under it. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Currency` | Type | The Move type for the `Currency` being added to the sending account of the transaction. `Currency` must be an already-registered currency on-chain. | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `Diem::ECURRENCY_INFO` | The `Currency` is not a registered currency on-chain. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EROLE_CANT_STORE_BALANCE` | The sending `account`'s role does not permit balances. | + /// | `Errors::ALREADY_PUBLISHED` | `DiemAccount::EADD_EXISTING_CURRENCY` | A balance for `Currency` is already published under the sending `account`. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_child_vasp_account` + /// * `AccountCreationScripts::create_parent_vasp_account` + /// * `PaymentScripts::peer_to_peer_with_metadata` + + public entry fun add_currency_to_account(account: signer) { + DiemAccount::add_currency(&account); + } + spec add_currency_to_account { + use std::errors; + use std::signer; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include DiemAccount::AddCurrencyAbortsIf; + include DiemAccount::AddCurrencyEnsures{addr: signer::address_of(account)}; + + aborts_with [check] + errors::NOT_PUBLISHED, + errors::INVALID_ARGUMENT, + errors::ALREADY_PUBLISHED; + + /// **Access Control:** + /// The account must be allowed to hold balances. Only Designated Dealers, Parent VASPs, + /// and Child VASPs can hold balances [[D1]][ROLE][[D2]][ROLE][[D3]][ROLE][[D4]][ROLE][[D5]][ROLE][[D6]][ROLE][[D7]][ROLE]. + aborts_if !Roles::can_hold_balance(account) with errors::INVALID_ARGUMENT; + } + + /// # Summary + /// Stores the sending accounts ability to rotate its authentication key with a designated recovery + /// account. Both the sending and recovery accounts need to belong to the same VASP and + /// both be VASP accounts. After this transaction both the sending account and the + /// specified recovery account can rotate the sender account's authentication key. + /// + /// # Technical Description + /// Adds the `DiemAccount::KeyRotationCapability` for the sending account + /// (`to_recover_account`) to the `RecoveryAddress::RecoveryAddress` resource under + /// `recovery_address`. After this transaction has been executed successfully the account at + /// `recovery_address` and the `to_recover_account` may rotate the authentication key of + /// `to_recover_account` (the sender of this transaction). + /// + /// The sending account of this transaction (`to_recover_account`) must not have previously given away its unique key + /// rotation capability, and must be a VASP account. The account at `recovery_address` + /// must also be a VASP account belonging to the same VASP as the `to_recover_account`. + /// Additionally the account at `recovery_address` must have already initialized itself as + /// a recovery account address using the `AccountAdministrationScripts::create_recovery_address` transaction script. + /// + /// The sending account's (`to_recover_account`) key rotation capability is + /// removed in this transaction and stored in the `RecoveryAddress::RecoveryAddress` + /// resource stored under the account at `recovery_address`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `to_recover_account` | `signer` | The signer of the sending account of this transaction. | + /// | `recovery_address` | `address` | The account address where the `to_recover_account`'s `DiemAccount::KeyRotationCapability` will be stored. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_STATE` | `DiemAccount::EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED` | `to_recover_account` has already delegated/extracted its `DiemAccount::KeyRotationCapability`. | + /// | `Errors::NOT_PUBLISHED` | `RecoveryAddress::ERECOVERY_ADDRESS` | `recovery_address` does not have a `RecoveryAddress` resource published under it. | + /// | `Errors::INVALID_ARGUMENT` | `RecoveryAddress::EINVALID_KEY_ROTATION_DELEGATION` | `to_recover_account` and `recovery_address` do not belong to the same VASP. | + /// | `Errors::LIMIT_EXCEEDED` | ` RecoveryAddress::EMAX_KEYS_REGISTERED` | `RecoveryAddress::MAX_REGISTERED_KEYS` have already been registered with this `recovery_address`. | + /// + /// # Related Scripts + /// * `AccountAdministrationScripts::create_recovery_address` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_recovery_address` + + public entry fun add_recovery_rotation_capability(to_recover_account: signer, recovery_address: address) { + RecoveryAddress::add_rotation_capability( + DiemAccount::extract_key_rotation_capability(&to_recover_account), recovery_address + ) + } + spec add_recovery_rotation_capability { + use std::signer; + use std::errors; + + include DiemAccount::TransactionChecks{sender: to_recover_account}; // properties checked by the prologue. + include DiemAccount::ExtractKeyRotationCapabilityAbortsIf{account: to_recover_account}; + include DiemAccount::ExtractKeyRotationCapabilityEnsures{account: to_recover_account}; + + let addr = signer::address_of(to_recover_account); + let rotation_cap = DiemAccount::spec_get_key_rotation_cap(addr); + + include RecoveryAddress::AddRotationCapabilityAbortsIf{ + to_recover: rotation_cap + }; + + ensures RecoveryAddress::spec_get_rotation_caps(recovery_address)[ + len(RecoveryAddress::spec_get_rotation_caps(recovery_address)) - 1] == rotation_cap; + + aborts_with [check] + errors::INVALID_STATE, + errors::NOT_PUBLISHED, + errors::LIMIT_EXCEEDED, + errors::INVALID_ARGUMENT; + } + + /// # Summary + /// Rotates the authentication key of the sending account to the newly-specified ed25519 public key and + /// publishes a new shared authentication key derived from that public key under the sender's account. + /// Any account can send this transaction. + /// + /// # Technical Description + /// Rotates the authentication key of the sending account to the + /// authentication key derived from `public_key` + /// and publishes a `SharedEd25519PublicKey::SharedEd25519PublicKey` resource + /// containing the 32-byte ed25519 `public_key` and the `DiemAccount::KeyRotationCapability` for + /// `account` under `account`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// | `public_key` | `vector` | A valid 32-byte Ed25519 public key for `account`'s authentication key to be rotated to and stored. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_STATE` | `DiemAccount::EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED` | `account` has already delegated/extracted its `DiemAccount::KeyRotationCapability` resource. | + /// | `Errors::ALREADY_PUBLISHED` | `SharedEd25519PublicKey::ESHARED_KEY` | The `SharedEd25519PublicKey::SharedEd25519PublicKey` resource is already published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SharedEd25519PublicKey::EMALFORMED_PUBLIC_KEY` | `public_key` is an invalid ed25519 public key. | + /// + /// # Related Scripts + /// * `AccountAdministrationScripts::rotate_shared_ed25519_public_key` + + public entry fun publish_shared_ed25519_public_key(account: signer, public_key: vector) { + SharedEd25519PublicKey::publish(&account, public_key) + } + spec publish_shared_ed25519_public_key { + use std::errors; + use DiemFramework::DiemAccount; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include SharedEd25519PublicKey::PublishAbortsIf{key: public_key}; + include SharedEd25519PublicKey::PublishEnsures{key: public_key}; + + aborts_with [check] + errors::INVALID_STATE, + errors::ALREADY_PUBLISHED, + errors::INVALID_ARGUMENT; + } + + /// # Summary + /// Rotates the `account`'s authentication key to the supplied new authentication key. May be sent by any account. + /// + /// # Technical Description + /// Rotate the `account`'s `DiemAccount::DiemAccount` `authentication_key` + /// field to `new_key`. `new_key` must be a valid authentication key that + /// corresponds to an ed25519 public key, + /// and `account` must not have previously delegated its `DiemAccount::KeyRotationCapability`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account of the transaction. | + /// | `new_key` | `vector` | New authentication key to be used for `account`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_STATE` | `DiemAccount::EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED` | `account` has already delegated/extracted its `DiemAccount::KeyRotationCapability`. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EMALFORMED_AUTHENTICATION_KEY` | `new_key` was an invalid length. | + /// + /// # Related Scripts + /// * `AccountAdministrationScripts::rotate_authentication_key_with_nonce` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_nonce_admin` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_recovery_address` + + public entry fun rotate_authentication_key(account: signer, new_key: vector) { + let key_rotation_capability = DiemAccount::extract_key_rotation_capability(&account); + DiemAccount::rotate_authentication_key(&key_rotation_capability, new_key); + DiemAccount::restore_key_rotation_capability(key_rotation_capability); + } + spec rotate_authentication_key { + use std::signer; + use std::errors; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + let account_addr = signer::address_of(account); + include DiemAccount::ExtractKeyRotationCapabilityAbortsIf; + let key_rotation_capability = DiemAccount::spec_get_key_rotation_cap(account_addr); + include DiemAccount::RotateAuthenticationKeyAbortsIf{cap: key_rotation_capability, new_authentication_key: new_key}; + + /// This rotates the authentication key of `account` to `new_key` + include DiemAccount::RotateAuthenticationKeyEnsures{addr: account_addr, new_authentication_key: new_key}; + + aborts_with [check] + errors::INVALID_STATE, + errors::INVALID_ARGUMENT; + + /// **Access Control:** + /// The account can rotate its own authentication key unless + /// it has delegrated the capability [[H18]][PERMISSION][[J18]][PERMISSION]. + include DiemAccount::AbortsIfDelegatedKeyRotationCapability; + } + + /// # Summary + /// Rotates the sender's authentication key to the supplied new authentication key. May be sent by + /// any account that has a sliding nonce resource published under it (usually this is Treasury + /// Compliance or Diem Root accounts). + /// + /// # Technical Description + /// Rotates the `account`'s `DiemAccount::DiemAccount` `authentication_key` + /// field to `new_key`. `new_key` must be a valid authentication key that + /// corresponds to an ed25519 public key, + /// and `account` must not have previously delegated its `DiemAccount::KeyRotationCapability`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account of the transaction. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `new_key` | `vector` | New authentication key to be used for `account`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::INVALID_STATE` | `DiemAccount::EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED` | `account` has already delegated/extracted its `DiemAccount::KeyRotationCapability`. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EMALFORMED_AUTHENTICATION_KEY` | `new_key` was an invalid length. | + /// + /// # Related Scripts + /// * `AccountAdministrationScripts::rotate_authentication_key` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_nonce_admin` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_recovery_address` + + public entry fun rotate_authentication_key_with_nonce(account: signer, sliding_nonce: u64, new_key: vector) { + SlidingNonce::record_nonce_or_abort(&account, sliding_nonce); + let key_rotation_capability = DiemAccount::extract_key_rotation_capability(&account); + DiemAccount::rotate_authentication_key(&key_rotation_capability, new_key); + DiemAccount::restore_key_rotation_capability(key_rotation_capability); + } + spec rotate_authentication_key_with_nonce { + use std::signer; + use std::errors; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + let account_addr = signer::address_of(account); + include SlidingNonce::RecordNonceAbortsIf{ seq_nonce: sliding_nonce }; + include DiemAccount::ExtractKeyRotationCapabilityAbortsIf; + let key_rotation_capability = DiemAccount::spec_get_key_rotation_cap(account_addr); + include DiemAccount::RotateAuthenticationKeyAbortsIf{cap: key_rotation_capability, new_authentication_key: new_key}; + + /// This rotates the authentication key of `account` to `new_key` + include DiemAccount::RotateAuthenticationKeyEnsures{addr: account_addr, new_authentication_key: new_key}; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::INVALID_STATE, + errors::NOT_PUBLISHED; + + /// **Access Control:** + /// The account can rotate its own authentication key unless + /// it has delegrated the capability [[H18]][PERMISSION][[J18]][PERMISSION]. + include DiemAccount::AbortsIfDelegatedKeyRotationCapability; + } + + /// # Summary + /// Rotates the specified account's authentication key to the supplied new authentication key. May + /// only be sent by the Diem Root account as a write set transaction. + /// + /// # Technical Description + /// Rotate the `account`'s `DiemAccount::DiemAccount` `authentication_key` field to `new_key`. + /// `new_key` must be a valid authentication key that corresponds to an ed25519 + /// public key, + /// and `account` must not have previously delegated its `DiemAccount::KeyRotationCapability`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | The signer of the sending account of the write set transaction. May only be the Diem Root signer. | + /// | `account` | `signer` | Signer of account specified in the `execute_as` field of the write set transaction. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction for Diem Root. | + /// | `new_key` | `vector` | New authentication key to be used for `account`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` in `dr_account` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` in `dr_account` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` in` dr_account` has been previously recorded. | + /// | `Errors::INVALID_STATE` | `DiemAccount::EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED` | `account` has already delegated/extracted its `DiemAccount::KeyRotationCapability`. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EMALFORMED_AUTHENTICATION_KEY` | `new_key` was an invalid length. | + /// + /// # Related Scripts + /// * `AccountAdministrationScripts::rotate_authentication_key` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_nonce` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_recovery_address` + + public entry fun rotate_authentication_key_with_nonce_admin(dr_account: signer, account: signer, sliding_nonce: u64, new_key: vector) { + SlidingNonce::record_nonce_or_abort(&dr_account, sliding_nonce); + let key_rotation_capability = DiemAccount::extract_key_rotation_capability(&account); + DiemAccount::rotate_authentication_key(&key_rotation_capability, new_key); + DiemAccount::restore_key_rotation_capability(key_rotation_capability); + } + spec rotate_authentication_key_with_nonce_admin { + use std::signer; + use std::errors; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + let account_addr = signer::address_of(account); + include SlidingNonce::RecordNonceAbortsIf{ account: dr_account, seq_nonce: sliding_nonce }; + include DiemAccount::ExtractKeyRotationCapabilityAbortsIf; + let key_rotation_capability = DiemAccount::spec_get_key_rotation_cap(account_addr); + include DiemAccount::RotateAuthenticationKeyAbortsIf{cap: key_rotation_capability, new_authentication_key: new_key}; + + /// This rotates the authentication key of `account` to `new_key` + include DiemAccount::RotateAuthenticationKeyEnsures{addr: account_addr, new_authentication_key: new_key}; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::INVALID_STATE, + errors::NOT_PUBLISHED; + + /// **Access Control:** + /// Only the Diem Root account can process the admin scripts [[H9]][PERMISSION]. + requires Roles::has_diem_root_role(dr_account); /// This is ensured by DiemAccount::writeset_prologue. + /// The account can rotate its own authentication key unless + /// it has delegrated the capability [[H18]][PERMISSION][[J18]][PERMISSION]. + include DiemAccount::AbortsIfDelegatedKeyRotationCapability{account: account}; + } + + /// # Summary + /// Rotates the authentication key of a specified account that is part of a recovery address to a + /// new authentication key. Only used for accounts that are part of a recovery address (see + /// `AccountAdministrationScripts::add_recovery_rotation_capability` for account restrictions). + /// + /// # Technical Description + /// Rotates the authentication key of the `to_recover` account to `new_key` using the + /// `DiemAccount::KeyRotationCapability` stored in the `RecoveryAddress::RecoveryAddress` resource + /// published under `recovery_address`. `new_key` must be a valide authentication key . + /// This transaction can be sent either by the `to_recover` account, or by the account where the + /// `RecoveryAddress::RecoveryAddress` resource is published that contains `to_recover`'s `DiemAccount::KeyRotationCapability`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account of the transaction. | + /// | `recovery_address` | `address` | Address where `RecoveryAddress::RecoveryAddress` that holds `to_recover`'s `DiemAccount::KeyRotationCapability` is published. | + /// | `to_recover` | `address` | The address of the account whose authentication key will be updated. | + /// | `new_key` | `vector` | New authentication key to be used for the account at the `to_recover` address. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `RecoveryAddress::ERECOVERY_ADDRESS` | `recovery_address` does not have a `RecoveryAddress::RecoveryAddress` resource published under it. | + /// | `Errors::INVALID_ARGUMENT` | `RecoveryAddress::ECANNOT_ROTATE_KEY` | The address of `account` is not `recovery_address` or `to_recover`. | + /// | `Errors::INVALID_ARGUMENT` | `RecoveryAddress::EACCOUNT_NOT_RECOVERABLE` | `to_recover`'s `DiemAccount::KeyRotationCapability` is not in the `RecoveryAddress::RecoveryAddress` resource published under `recovery_address`. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EMALFORMED_AUTHENTICATION_KEY` | `new_key` was an invalid length. | + /// + /// # Related Scripts + /// * `AccountAdministrationScripts::rotate_authentication_key` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_nonce` + /// * `AccountAdministrationScripts::rotate_authentication_key_with_nonce_admin` + + public entry fun rotate_authentication_key_with_recovery_address( + account: signer, + recovery_address: address, + to_recover: address, + new_key: vector + ) { + RecoveryAddress::rotate_authentication_key(&account, recovery_address, to_recover, new_key) + } + spec rotate_authentication_key_with_recovery_address { + use std::errors; + use DiemFramework::DiemAccount; + use std::signer; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include RecoveryAddress::RotateAuthenticationKeyAbortsIf; + include RecoveryAddress::RotateAuthenticationKeyEnsures; + + aborts_with [check] + errors::NOT_PUBLISHED, + errors::INVALID_ARGUMENT; + + /// **Access Control:** + /// The delegatee at the recovery address has to hold the key rotation capability for + /// the address to recover. The address of the transaction signer has to be either + /// the delegatee's address or the address to recover [[H18]][PERMISSION][[J18]][PERMISSION]. + let account_addr = signer::address_of(account); + aborts_if !RecoveryAddress::spec_holds_key_rotation_cap_for(recovery_address, to_recover) with errors::INVALID_ARGUMENT; + aborts_if !(account_addr == recovery_address || account_addr == to_recover) with errors::INVALID_ARGUMENT; + } + + /// # Summary + /// Updates the url used for off-chain communication, and the public key used to verify dual + /// attestation on-chain. Transaction can be sent by any account that has dual attestation + /// information published under it. In practice the only such accounts are Designated Dealers and + /// Parent VASPs. + /// + /// # Technical Description + /// Updates the `base_url` and `compliance_public_key` fields of the `DualAttestation::Credential` + /// resource published under `account`. The `new_key` must be a valid ed25519 public key. + /// + /// # Events + /// Successful execution of this transaction emits two events: + /// * A `DualAttestation::ComplianceKeyRotationEvent` containing the new compliance public key, and + /// the blockchain time at which the key was updated emitted on the `DualAttestation::Credential` + /// `compliance_key_rotation_events` handle published under `account`; and + /// * A `DualAttestation::BaseUrlRotationEvent` containing the new base url to be used for + /// off-chain communication, and the blockchain time at which the url was updated emitted on the + /// `DualAttestation::Credential` `base_url_rotation_events` handle published under `account`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account of the transaction. | + /// | `new_url` | `vector` | ASCII-encoded url to be used for off-chain communication with `account`. | + /// | `new_key` | `vector` | New ed25519 public key to be used for on-chain dual attestation checking. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `DualAttestation::ECREDENTIAL` | A `DualAttestation::Credential` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `DualAttestation::EINVALID_PUBLIC_KEY` | `new_key` is not a valid ed25519 public key. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_parent_vasp_account` + /// * `AccountCreationScripts::create_designated_dealer` + /// * `AccountAdministrationScripts::rotate_dual_attestation_info` + + public entry fun rotate_dual_attestation_info(account: signer, new_url: vector, new_key: vector) { + DualAttestation::rotate_base_url(&account, new_url); + DualAttestation::rotate_compliance_public_key(&account, new_key) + } + spec rotate_dual_attestation_info { + use std::errors; + use DiemFramework::DiemAccount; + use std::signer; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include DualAttestation::RotateBaseUrlAbortsIf; + include DualAttestation::RotateBaseUrlEnsures; + include DualAttestation::RotateCompliancePublicKeyAbortsIf; + include DualAttestation::RotateCompliancePublicKeyEnsures; + + aborts_with [check] + errors::NOT_PUBLISHED, + errors::INVALID_ARGUMENT; + + include DualAttestation::RotateBaseUrlEmits; + include DualAttestation::RotateCompliancePublicKeyEmits; + + /// **Access Control:** + /// Only the account having Credential can rotate the info. + /// Credential is granted to either a Parent VASP or a designated dealer [[H17]][PERMISSION]. + include DualAttestation::AbortsIfNoCredential{addr: signer::address_of(account)}; + } + + /// # Summary + /// Rotates the authentication key in a `SharedEd25519PublicKey`. This transaction can be sent by + /// any account that has previously published a shared ed25519 public key using + /// `AccountAdministrationScripts::publish_shared_ed25519_public_key`. + /// + /// # Technical Description + /// `public_key` must be a valid ed25519 public key. This transaction first rotates the public key stored in `account`'s + /// `SharedEd25519PublicKey::SharedEd25519PublicKey` resource to `public_key`, after which it + /// rotates the `account`'s authentication key to the new authentication key derived from `public_key` + /// using the `DiemAccount::KeyRotationCapability` stored in `account`'s `SharedEd25519PublicKey::SharedEd25519PublicKey`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// | `public_key` | `vector` | 32-byte Ed25519 public key. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SharedEd25519PublicKey::ESHARED_KEY` | A `SharedEd25519PublicKey::SharedEd25519PublicKey` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SharedEd25519PublicKey::EMALFORMED_PUBLIC_KEY` | `public_key` is an invalid ed25519 public key. | + /// + /// # Related Scripts + /// * `AccountAdministrationScripts::publish_shared_ed25519_public_key` + + public entry fun rotate_shared_ed25519_public_key(account: signer, public_key: vector) { + SharedEd25519PublicKey::rotate_key(&account, public_key) + } + spec rotate_shared_ed25519_public_key { + use std::errors; + use DiemFramework::DiemAccount; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include SharedEd25519PublicKey::RotateKeyAbortsIf{new_public_key: public_key}; + include SharedEd25519PublicKey::RotateKeyEnsures{new_public_key: public_key}; + + aborts_with [check] + errors::NOT_PUBLISHED, + errors::INVALID_ARGUMENT; + } + + /// # Summary + /// Initializes the sending account as a recovery address that may be used by + /// other accounts belonging to the same VASP as `account`. + /// The sending account must be a VASP account, and can be either a child or parent VASP account. + /// Multiple recovery addresses can exist for a single VASP, but accounts in + /// each must be disjoint. + /// + /// # Technical Description + /// Publishes a `RecoveryAddress::RecoveryAddress` resource under `account`. It then + /// extracts the `DiemAccount::KeyRotationCapability` for `account` and adds + /// it to the resource. After the successful execution of this transaction + /// other accounts may add their key rotation to this resource so that `account` + /// may be used as a recovery account for those accounts. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_STATE` | `DiemAccount::EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED` | `account` has already delegated/extracted its `DiemAccount::KeyRotationCapability`. | + /// | `Errors::INVALID_ARGUMENT` | `RecoveryAddress::ENOT_A_VASP` | `account` is not a VASP account. | + /// | `Errors::INVALID_ARGUMENT` | `RecoveryAddress::EKEY_ROTATION_DEPENDENCY_CYCLE` | A key rotation recovery cycle would be created by adding `account`'s key rotation capability. | + /// | `Errors::ALREADY_PUBLISHED` | `RecoveryAddress::ERECOVERY_ADDRESS` | A `RecoveryAddress::RecoveryAddress` resource has already been published under `account`. | + /// + /// # Related Scripts + /// * `Script::add_recovery_rotation_capability` + /// * `Script::rotate_authentication_key_with_recovery_address` + + public entry fun create_recovery_address(account: signer) { + RecoveryAddress::publish(&account, DiemAccount::extract_key_rotation_capability(&account)) + } + + spec create_recovery_address { + use std::signer; + use std::errors; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include DiemAccount::ExtractKeyRotationCapabilityAbortsIf; + include DiemAccount::ExtractKeyRotationCapabilityEnsures; + + let account_addr = signer::address_of(account); + let rotation_cap = DiemAccount::spec_get_key_rotation_cap(account_addr); + + include RecoveryAddress::PublishAbortsIf{ + recovery_account: account, + rotation_cap: rotation_cap + }; + + ensures RecoveryAddress::spec_is_recovery_address(account_addr); + ensures len(RecoveryAddress::spec_get_rotation_caps(account_addr)) == 1; + ensures RecoveryAddress::spec_get_rotation_caps(account_addr)[0] == rotation_cap; + + aborts_with [check] + errors::INVALID_STATE, + errors::INVALID_ARGUMENT, + errors::ALREADY_PUBLISHED; + } + + /// # Summary + /// Publishes a `VASPDomain::VASPDomains` resource under a parent VASP account. + /// The sending account must be a parent VASP account. + /// + /// # Technical Description + /// Publishes a `VASPDomain::VASPDomains` resource under `account`. + /// The The `VASPDomain::VASPDomains` resource's `domains` field is a vector + /// of VASPDomain, and will be empty on at the end of processing this transaction. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::ALREADY_PUBLISHED` | `VASPDomain::EVASP_DOMAINS` | A `VASPDomain::VASPDomains` resource has already been published under `account`. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EPARENT_VASP` | The sending `account` was not a parent VASP account. | + public entry fun create_vasp_domains(account: signer) { + VASPDomain::publish_vasp_domains(&account) + } + spec create_vasp_domains { + use DiemFramework::Roles; + use std::errors; + use std::signer; + + let vasp_addr = signer::address_of(account); + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include Roles::AbortsIfNotParentVasp; + include VASPDomain::PublishVASPDomainsAbortsIf { vasp_addr }; + include VASPDomain::PublishVASPDomainsEnsures { vasp_addr }; + + aborts_with [check] + errors::ALREADY_PUBLISHED, + errors::REQUIRES_ROLE; + } + + /// # Summary + /// Publishes a CRSN resource under `account` and opts the account in to + /// concurrent transaction processing. Upon successful execution of this + /// script, all further transactions sent from this account will be ordered + /// and processed according to DIP-168. + /// + /// # Technical Description + /// This publishes a `CRSN::CRSN` resource under `account` with `crsn_size` + /// number of slots. All slots will be initialized to the empty (unused) + /// state, and the CRSN resource's `min_nonce` field will be set to the transaction's + /// sequence number + 1. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// | `crsn_size` | `u64` | The the number of slots the published CRSN will have. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_STATE` | `CRSN::EHAS_CRSN` | A `CRSN::CRSN` resource was already published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `CRSN::EZERO_SIZE_CRSN` | The `crsn_size` was zero. | + public entry fun opt_in_to_crsn(account: signer, crsn_size: u64) { + DiemAccount::publish_crsn(&account, crsn_size) + } + + /// # Summary + /// Shifts the window held by the CRSN resource published under `account` + /// by `shift_amount`. This will expire all unused slots in the CRSN at the + /// time of processing that are less than `shift_amount`. The exact + /// semantics are defined in DIP-168. + /// + /// # Technical Description + /// This shifts the slots in the published `CRSN::CRSN` resource under + /// `account` by `shift_amount`, and increments the CRSN's `min_nonce` field + /// by `shift_amount` as well. After this, it will shift the window over + /// any set bits. It is important to note that the sequence nonce of the + /// sending transaction must still lie within the range of the window in + /// order for this transaction to be processed successfully. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// | `shift_amount` | `u64` | The amount to shift the window in the CRSN under `account`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_STATE` | `CRSN::ENO_CRSN` | A `CRSN::CRSN` resource is not published under `account`. | + public entry fun force_expire(account: signer, shift_amount: u64) { + CRSN::force_expire(&account, shift_amount) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountCreationScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountCreationScripts.move new file mode 100644 index 000000000..80c717ca5 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountCreationScripts.move @@ -0,0 +1,510 @@ +module DiemFramework::AccountCreationScripts { + use DiemFramework::DiemAccount; + use DiemFramework::SlidingNonce; + + /// # Summary + /// Creates a Child VASP account with its parent being the sending account of the transaction. + /// The sender of the transaction must be a Parent VASP account. + /// + /// # Technical Description + /// Creates a `ChildVASP` account for the sender `parent_vasp` at `child_address` with a balance of + /// `child_initial_balance` in `CoinType` and an initial authentication key of + /// `auth_key_prefix | child_address`. + /// + /// If `add_all_currencies` is true, the child address will have a zero balance in all available + /// currencies in the system. + /// + /// The new account will be a child account of the transaction sender, which must be a + /// Parent VASP account. The child account will be recorded against the limit of + /// child accounts of the creating Parent VASP account. + /// + /// # Events + /// Successful execution will emit: + /// * A `DiemAccount::CreateAccountEvent` with the `created` field being `child_address`, + /// and the `rold_id` field being `Roles::CHILD_VASP_ROLE_ID`. This is emitted on the + /// `DiemAccount::AccountOperationsCapability` `creation_events` handle. + /// + /// Successful execution with a `child_initial_balance` greater than zero will additionaly emit: + /// * A `DiemAccount::SentPaymentEvent` with the `payee` field being `child_address`. + /// This is emitted on the Parent VASP's `DiemAccount::DiemAccount` `sent_events` handle. + /// * A `DiemAccount::ReceivedPaymentEvent` with the `payer` field being the Parent VASP's address. + /// This is emitted on the new Child VASPS's `DiemAccount::DiemAccount` `received_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `CoinType` | Type | The Move type for the `CoinType` that the child account should be created with. `CoinType` must be an already-registered currency on-chain. | + /// | `parent_vasp` | `signer` | The reference of the sending account. Must be a Parent VASP account. | + /// | `child_address` | `address` | Address of the to-be-created Child VASP account. | + /// | `auth_key_prefix` | `vector` | The authentication key prefix that will be used initially for the newly created account. | + /// | `add_all_currencies` | `bool` | Whether to publish balance resources for all known currencies when the account is created. | + /// | `child_initial_balance` | `u64` | The initial balance in `CoinType` to give the child account when it's created. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EMALFORMED_AUTHENTICATION_KEY` | The `auth_key_prefix` was not of length 32. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EPARENT_VASP` | The sending account wasn't a Parent VASP account. | + /// | `Errors::ALREADY_PUBLISHED` | `Roles::EROLE_ID` | The `child_address` address is already taken. | + /// | `Errors::LIMIT_EXCEEDED` | `VASP::ETOO_MANY_CHILDREN` | The sending account has reached the maximum number of allowed child accounts. | + /// | `Errors::NOT_PUBLISHED` | `Diem::ECURRENCY_INFO` | The `CoinType` is not a registered currency on-chain. | + /// | `Errors::INVALID_STATE` | `DiemAccount::EWITHDRAWAL_CAPABILITY_ALREADY_EXTRACTED` | The withdrawal capability for the sending account has already been extracted. | + /// | `Errors::NOT_PUBLISHED` | `DiemAccount::EPAYER_DOESNT_HOLD_CURRENCY` | The sending account doesn't have a balance in `CoinType`. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EINSUFFICIENT_BALANCE` | The sending account doesn't have at least `child_initial_balance` of `CoinType` balance. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::ECANNOT_CREATE_AT_VM_RESERVED` | The `child_address` is the reserved address 0x0. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_parent_vasp_account` + /// * `AccountAdministrationScripts::add_currency_to_account` + /// * `AccountAdministrationScripts::rotate_authentication_key` + /// * `AccountAdministrationScripts::add_recovery_rotation_capability` + /// * `AccountAdministrationScripts::create_recovery_address` + + public entry fun create_child_vasp_account( + parent_vasp: signer, + child_address: address, + auth_key_prefix: vector, + add_all_currencies: bool, + child_initial_balance: u64 + ) { + DiemAccount::create_child_vasp_account( + &parent_vasp, + child_address, + auth_key_prefix, + add_all_currencies, + ); + // Give the newly created child `child_initial_balance` coins + if (child_initial_balance > 0) { + let vasp_withdrawal_cap = DiemAccount::extract_withdraw_capability(&parent_vasp); + DiemAccount::pay_from( + &vasp_withdrawal_cap, child_address, child_initial_balance, x"", x"" + ); + DiemAccount::restore_withdraw_capability(vasp_withdrawal_cap); + }; + } + + spec create_child_vasp_account { + use std::signer; + use std::errors; + use DiemFramework::DualAttestation; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: parent_vasp}; // properties checked by the prologue. + let parent_addr = signer::address_of(parent_vasp); + let parent_cap = DiemAccount::spec_get_withdraw_cap(parent_addr); + include DiemAccount::CreateChildVASPAccountAbortsIf{ + parent: parent_vasp, new_account_address: child_address}; + aborts_if child_initial_balance > max_u64() with errors::LIMIT_EXCEEDED; + include (child_initial_balance > 0) ==> + DiemAccount::ExtractWithdrawCapAbortsIf{sender_addr: parent_addr}; + include (child_initial_balance > 0) ==> DualAttestation::AssertPaymentOkAbortsIf{ + payer: parent_addr, + payee: child_address, + metadata: x"", + metadata_signature: x"", + value: child_initial_balance + }; + include (child_initial_balance) > 0 ==> + DiemAccount::PayFromAbortsIfRestricted{ + cap: parent_cap, + payee: child_address, + amount: child_initial_balance, + metadata: x"", + }; + include DiemAccount::CreateChildVASPAccountEnsures{ + parent_addr: parent_addr, + child_addr: child_address, + }; + ensures DiemAccount::balance(child_address) == child_initial_balance; + ensures DiemAccount::balance(parent_addr) + == old(DiemAccount::balance(parent_addr)) - child_initial_balance; + + aborts_with [check] + errors::REQUIRES_ROLE, + errors::ALREADY_PUBLISHED, + errors::LIMIT_EXCEEDED, + errors::NOT_PUBLISHED, + errors::INVALID_STATE, + errors::INVALID_ARGUMENT; + + // TODO: fix emit specs below + /* + include DiemAccount::MakeAccountEmits{new_account_address: child_address}; + include child_initial_balance > 0 ==> + DiemAccount::PayFromEmits{ + cap: parent_cap, + payee: child_address, + amount: child_initial_balance, + metadata: x"", + }; + */ + + /// **Access Control:** + /// Only Parent VASP accounts can create Child VASP accounts [[A7]][ROLE]. + include Roles::AbortsIfNotParentVasp{account: parent_vasp}; + } + + /// # Summary + /// Creates a Validator Operator account. This transaction can only be sent by the Diem + /// Root account. + /// + /// # Technical Description + /// Creates an account with a Validator Operator role at `new_account_address`, with authentication key + /// `auth_key_prefix` | `new_account_address`. It publishes a + /// `ValidatorOperatorConfig::ValidatorOperatorConfig` resource with the specified `human_name`. + /// This script does not assign the validator operator to any validator accounts but only creates the account. + /// + /// # Events + /// Successful execution will emit: + /// * A `DiemAccount::CreateAccountEvent` with the `created` field being `new_account_address`, + /// and the `rold_id` field being `Roles::VALIDATOR_OPERATOR_ROLE_ID`. This is emitted on the + /// `DiemAccount::AccountOperationsCapability` `creation_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | The signer of the sending account of this transaction. Must be the Diem Root signer. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `new_account_address` | `address` | Address of the to-be-created Validator account. | + /// | `auth_key_prefix` | `vector` | The authentication key prefix that will be used initially for the newly created account. | + /// | `human_name` | `vector` | ASCII-encoded human name for the validator. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::ALREADY_PUBLISHED` | `Roles::EROLE_ID` | The `new_account_address` address is already taken. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun create_validator_operator_account( + dr_account: signer, + sliding_nonce: u64, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector + ) { + SlidingNonce::record_nonce_or_abort(&dr_account, sliding_nonce); + DiemAccount::create_validator_operator_account( + &dr_account, + new_account_address, + auth_key_prefix, + human_name, + ); + } + + /// Only Diem root may create Validator Operator accounts + /// Authentication: ValidatorAccountAbortsIf includes AbortsIfNotDiemRoot. + /// Checks that above table includes all error categories. + /// The verifier finds an abort that is not documented, and cannot occur in practice: + /// * REQUIRES_ROLE comes from `Roles::assert_diem_root`. However, assert_diem_root checks the literal + /// Diem root address before checking the role, and the role abort is unreachable in practice, since + /// only Diem root has the Diem root role. + spec create_validator_operator_account { + use std::errors; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: dr_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{seq_nonce: sliding_nonce, account: dr_account}; + include DiemAccount::CreateValidatorOperatorAccountAbortsIf; + include DiemAccount::CreateValidatorOperatorAccountEnsures; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::NOT_PUBLISHED, + errors::REQUIRES_ADDRESS, + errors::ALREADY_PUBLISHED, + errors::REQUIRES_ROLE; + + include DiemAccount::MakeAccountEmits; + + /// **Access Control:** + /// Only the Diem Root account can create Validator Operator accounts [[A4]][ROLE]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + } + + /// # Summary + /// Creates a Validator account. This transaction can only be sent by the Diem + /// Root account. + /// + /// # Technical Description + /// Creates an account with a Validator role at `new_account_address`, with authentication key + /// `auth_key_prefix` | `new_account_address`. It publishes a + /// `ValidatorConfig::ValidatorConfig` resource with empty `config`, and + /// `operator_account` fields. The `human_name` field of the + /// `ValidatorConfig::ValidatorConfig` is set to the passed in `human_name`. + /// This script does not add the validator to the validator set or the system, + /// but only creates the account. + /// + /// # Events + /// Successful execution will emit: + /// * A `DiemAccount::CreateAccountEvent` with the `created` field being `new_account_address`, + /// and the `rold_id` field being `Roles::VALIDATOR_ROLE_ID`. This is emitted on the + /// `DiemAccount::AccountOperationsCapability` `creation_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | The signer of the sending account of this transaction. Must be the Diem Root signer. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `new_account_address` | `address` | Address of the to-be-created Validator account. | + /// | `auth_key_prefix` | `vector` | The authentication key prefix that will be used initially for the newly created account. | + /// | `human_name` | `vector` | ASCII-encoded human name for the validator. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::ALREADY_PUBLISHED` | `Roles::EROLE_ID` | The `new_account_address` address is already taken. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun create_validator_account( + dr_account: signer, + sliding_nonce: u64, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + ) { + SlidingNonce::record_nonce_or_abort(&dr_account, sliding_nonce); + DiemAccount::create_validator_account( + &dr_account, + new_account_address, + auth_key_prefix, + human_name, + ); + } + + /// Only Diem root may create Validator accounts + /// Authentication: ValidatorAccountAbortsIf includes AbortsIfNotDiemRoot. + /// Checks that above table includes all error categories. + /// The verifier finds an abort that is not documented, and cannot occur in practice: + /// * REQUIRES_ROLE comes from `Roles::assert_diem_root`. However, assert_diem_root checks the literal + /// Diem root address before checking the role, and the role abort is unreachable in practice, since + /// only Diem root has the Diem root role. + spec create_validator_account { + use std::errors; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: dr_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{seq_nonce: sliding_nonce, account: dr_account}; + include DiemAccount::CreateValidatorAccountAbortsIf; + include DiemAccount::CreateValidatorAccountEnsures; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::NOT_PUBLISHED, + errors::REQUIRES_ADDRESS, + errors::ALREADY_PUBLISHED, + errors::REQUIRES_ROLE; + + include DiemAccount::MakeAccountEmits; + + /// **Access Control:** + /// Only the Diem Root account can create Validator accounts [[A3]][ROLE]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + } + + /// # Summary + /// Creates a Parent VASP account with the specified human name. Must be called by the Treasury Compliance account. + /// + /// # Technical Description + /// Creates an account with the Parent VASP role at `address` with authentication key + /// `auth_key_prefix` | `new_account_address` and a 0 balance of type `CoinType`. If + /// `add_all_currencies` is true, 0 balances for all available currencies in the system will + /// also be added. This can only be invoked by an TreasuryCompliance account. + /// `sliding_nonce` is a unique nonce for operation, see `SlidingNonce` for details. + /// + /// # Events + /// Successful execution will emit: + /// * A `DiemAccount::CreateAccountEvent` with the `created` field being `new_account_address`, + /// and the `rold_id` field being `Roles::PARENT_VASP_ROLE_ID`. This is emitted on the + /// `DiemAccount::AccountOperationsCapability` `creation_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `CoinType` | Type | The Move type for the `CoinType` currency that the Parent VASP account should be initialized with. `CoinType` must be an already-registered currency on-chain. | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `new_account_address` | `address` | Address of the to-be-created Parent VASP account. | + /// | `auth_key_prefix` | `vector` | The authentication key prefix that will be used initially for the newly created account. | + /// | `human_name` | `vector` | ASCII-encoded human name for the Parent VASP. | + /// | `add_all_currencies` | `bool` | Whether to publish balance resources for all known currencies when the account is created. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `tc_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `Diem::ECURRENCY_INFO` | The `CoinType` is not a registered currency on-chain. | + /// | `Errors::ALREADY_PUBLISHED` | `Roles::EROLE_ID` | The `new_account_address` address is already taken. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_child_vasp_account` + /// * `AccountAdministrationScripts::add_currency_to_account` + /// * `AccountAdministrationScripts::rotate_authentication_key` + /// * `AccountAdministrationScripts::add_recovery_rotation_capability` + /// * `AccountAdministrationScripts::create_recovery_address` + /// * `AccountAdministrationScripts::rotate_dual_attestation_info` + + public entry fun create_parent_vasp_account( + tc_account: signer, + sliding_nonce: u64, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + add_all_currencies: bool + ) { + SlidingNonce::record_nonce_or_abort(&tc_account, sliding_nonce); + DiemAccount::create_parent_vasp_account( + &tc_account, + new_account_address, + auth_key_prefix, + human_name, + add_all_currencies + ); + } + + spec create_parent_vasp_account { + use std::errors; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: tc_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{account: tc_account, seq_nonce: sliding_nonce}; + include DiemAccount::CreateParentVASPAccountAbortsIf{creator_account: tc_account}; + include DiemAccount::CreateParentVASPAccountEnsures; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::REQUIRES_ADDRESS, + errors::NOT_PUBLISHED, + errors::ALREADY_PUBLISHED, + errors::REQUIRES_ROLE; + + include DiemAccount::MakeAccountEmits; + + /// **Access Control:** + /// Only the Treasury Compliance account can create Parent VASP accounts [[A6]][ROLE]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + } + + /// # Summary + /// Creates a Designated Dealer account with the provided information, and initializes it with + /// default mint tiers. The transaction can only be sent by the Treasury Compliance account. + /// + /// # Technical Description + /// Creates an account with the Designated Dealer role at `addr` with authentication key + /// `auth_key_prefix` | `addr` and a 0 balance of type `Currency`. If `add_all_currencies` is true, + /// 0 balances for all available currencies in the system will also be added. This can only be + /// invoked by an account with the TreasuryCompliance role. + /// + /// At the time of creation the account is also initialized with default mint tiers of (500_000, + /// 5000_000, 50_000_000, 500_000_000), and preburn areas for each currency that is added to the + /// account. + /// + /// # Events + /// Successful execution will emit: + /// * A `DiemAccount::CreateAccountEvent` with the `created` field being `addr`, + /// and the `rold_id` field being `Roles::DESIGNATED_DEALER_ROLE_ID`. This is emitted on the + /// `DiemAccount::AccountOperationsCapability` `creation_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Currency` | Type | The Move type for the `Currency` that the Designated Dealer should be initialized with. `Currency` must be an already-registered currency on-chain. | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `addr` | `address` | Address of the to-be-created Designated Dealer account. | + /// | `auth_key_prefix` | `vector` | The authentication key prefix that will be used initially for the newly created account. | + /// | `human_name` | `vector` | ASCII-encoded human name for the Designated Dealer. | + /// | `add_all_currencies` | `bool` | Whether to publish preburn, balance, and tier info resources for all known (SCS) currencies or just `Currency` when the account is created. | + /// + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `tc_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `Diem::ECURRENCY_INFO` | The `Currency` is not a registered currency on-chain. | + /// | `Errors::ALREADY_PUBLISHED` | `Roles::EROLE_ID` | The `addr` address is already taken. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::tiered_mint` + /// * `PaymentScripts::peer_to_peer_with_metadata` + /// * `AccountAdministrationScripts::rotate_dual_attestation_info` + + public entry fun create_designated_dealer( + tc_account: signer, + sliding_nonce: u64, + addr: address, + auth_key_prefix: vector, + human_name: vector, + add_all_currencies: bool, + ) { + SlidingNonce::record_nonce_or_abort(&tc_account, sliding_nonce); + DiemAccount::create_designated_dealer( + &tc_account, + addr, + auth_key_prefix, + human_name, + add_all_currencies + ); + } + + spec create_designated_dealer { + use std::errors; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: tc_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{account: tc_account, seq_nonce: sliding_nonce}; + include DiemAccount::CreateDesignatedDealerAbortsIf{ + creator_account: tc_account, new_account_address: addr}; + include DiemAccount::CreateDesignatedDealerEnsures{new_account_address: addr}; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::REQUIRES_ADDRESS, + errors::NOT_PUBLISHED, + errors::ALREADY_PUBLISHED, + errors::REQUIRES_ROLE; + + include DiemAccount::MakeAccountEmits{new_account_address: addr}; + + /// **Access Control:** + /// Only the Treasury Compliance account can create Designated Dealer accounts [[A5]][ROLE]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountFreezing.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountFreezing.move new file mode 100644 index 000000000..0859e92e0 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountFreezing.move @@ -0,0 +1,235 @@ +/// Module which manages freezing of accounts. +module DiemFramework::AccountFreezing { + use DiemFramework::DiemTimestamp; + use DiemFramework::CoreAddresses; + use DiemFramework::Roles; + use std::event::{Self, EventHandle}; + use std::errors; + use std::signer; + friend DiemFramework::DiemAccount; + + struct FreezingBit has key { + /// If `is_frozen` is set true, the account cannot be used to send transactions or receive funds + is_frozen: bool, + } + + struct FreezeEventsHolder has key { + freeze_event_handle: EventHandle, + unfreeze_event_handle: EventHandle, + } + + /// Message for freeze account events + struct FreezeAccountEvent has drop, store { + /// The address that initiated freeze txn + initiator_address: address, + /// The address that was frozen + frozen_address: address, + } + + /// Message for unfreeze account events + struct UnfreezeAccountEvent has drop, store { + /// The address that initiated unfreeze txn + initiator_address: address, + /// The address that was unfrozen + unfrozen_address: address, + } + + /// A property expected of the `FreezeEventsHolder` resource didn't hold + const EFREEZE_EVENTS_HOLDER: u64 = 1; + /// The `FreezingBit` resource is in an invalid state + const EFREEZING_BIT: u64 = 2; + /// An attempt to freeze the Diem Root account was attempted + const ECANNOT_FREEZE_DIEM_ROOT: u64 = 3; + /// An attempt to freeze the Treasury & Compliance account was attempted + const ECANNOT_FREEZE_TC: u64 = 4; + /// The account is frozen + const EACCOUNT_FROZEN: u64 = 5; + + public fun initialize(dr_account: &signer) { + DiemTimestamp::assert_genesis(); + CoreAddresses::assert_diem_root(dr_account); + assert!( + !exists(signer::address_of(dr_account)), + errors::already_published(EFREEZE_EVENTS_HOLDER) + ); + move_to(dr_account, FreezeEventsHolder { + freeze_event_handle: event::new_event_handle(dr_account), + unfreeze_event_handle: event::new_event_handle(dr_account), + }); + } + spec initialize { + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + let addr = signer::address_of(dr_account); + aborts_if exists(addr) with errors::ALREADY_PUBLISHED; + ensures exists(addr); + } + + public(friend) fun create(account: &signer) { + let addr = signer::address_of(account); + assert!(!exists(addr), errors::already_published(EFREEZING_BIT)); + move_to(account, FreezingBit { is_frozen: false }) + } + spec create { + let addr = signer::address_of(account); + modifies global(addr); + aborts_if exists(addr) with errors::ALREADY_PUBLISHED; + ensures spec_account_is_not_frozen(addr); + } + + /// Freeze the account at `addr`. + public fun freeze_account( + account: &signer, + frozen_address: address, + ) + acquires FreezingBit, FreezeEventsHolder { + DiemTimestamp::assert_operating(); + Roles::assert_treasury_compliance(account); + // The diem root account and TC cannot be frozen + assert!(frozen_address != @DiemRoot, errors::invalid_argument(ECANNOT_FREEZE_DIEM_ROOT)); + assert!(frozen_address != @TreasuryCompliance, errors::invalid_argument(ECANNOT_FREEZE_TC)); + assert!(exists(frozen_address), errors::not_published(EFREEZING_BIT)); + borrow_global_mut(frozen_address).is_frozen = true; + let initiator_address = signer::address_of(account); + event::emit_event( + &mut borrow_global_mut(@DiemRoot).freeze_event_handle, + FreezeAccountEvent { + initiator_address, + frozen_address + }, + ); + } + spec freeze_account { + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotTreasuryCompliance; + aborts_if frozen_address == @DiemRoot with errors::INVALID_ARGUMENT; + aborts_if frozen_address == @TreasuryCompliance with errors::INVALID_ARGUMENT; + aborts_if !exists(frozen_address) with errors::NOT_PUBLISHED; + ensures spec_account_is_frozen(frozen_address); + include FreezeAccountEmits; + } + spec schema FreezeAccountEmits { + account: &signer; + frozen_address: address; + let handle = global(@DiemRoot).freeze_event_handle; + let msg = FreezeAccountEvent { + initiator_address: signer::address_of(account), + frozen_address + }; + emits msg to handle; + } + + /// Unfreeze the account at `addr`. + public fun unfreeze_account( + account: &signer, + unfrozen_address: address, + ) + acquires FreezingBit, FreezeEventsHolder { + DiemTimestamp::assert_operating(); + Roles::assert_treasury_compliance(account); + assert!(exists(unfrozen_address), errors::not_published(EFREEZING_BIT)); + borrow_global_mut(unfrozen_address).is_frozen = false; + let initiator_address = signer::address_of(account); + event::emit_event( + &mut borrow_global_mut(@DiemRoot).unfreeze_event_handle, + UnfreezeAccountEvent { + initiator_address, + unfrozen_address + }, + ); + } + spec unfreeze_account { + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotTreasuryCompliance; + aborts_if !exists(unfrozen_address) with errors::NOT_PUBLISHED; + ensures !spec_account_is_frozen(unfrozen_address); + include UnfreezeAccountEmits; + } + spec schema UnfreezeAccountEmits { + account: &signer; + unfrozen_address: address; + let handle = global(@DiemRoot).unfreeze_event_handle; + let msg = UnfreezeAccountEvent { + initiator_address: signer::address_of(account), + unfrozen_address + }; + emits msg to handle; + } + + /// Returns if the account at `addr` is frozen. + public fun account_is_frozen(addr: address): bool + acquires FreezingBit { + exists(addr) && borrow_global(addr).is_frozen + } + spec account_is_frozen { + aborts_if false; + pragma opaque = true; + ensures result == spec_account_is_frozen(addr); + } + + /// Assert that an account is not frozen. + public fun assert_not_frozen(account: address) acquires FreezingBit { + assert!(!account_is_frozen(account), errors::invalid_state(EACCOUNT_FROZEN)); + } + spec assert_not_frozen { + pragma opaque; + include AbortsIfFrozen; + } + spec schema AbortsIfFrozen { + account: address; + aborts_if spec_account_is_frozen(account) with errors::INVALID_STATE; + } + + #[test_only] + public fun create_for_test(account: &signer) { + create(account) + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Initialization + spec module { + /// `FreezeEventsHolder` always exists after genesis. + invariant [suspendable] DiemTimestamp::is_operating() ==> + exists(@DiemRoot); + } + + /// # Access Control + spec module { + /// The account of DiemRoot is not freezable [[F1]][ROLE]. + /// After genesis, FreezingBit of DiemRoot is always false. + invariant [suspendable] DiemTimestamp::is_operating() ==> + spec_account_is_not_frozen(@DiemRoot); + + /// The account of TreasuryCompliance is not freezable [[F2]][ROLE]. + /// After genesis, FreezingBit of TreasuryCompliance is always false. + invariant [suspendable] DiemTimestamp::is_operating() ==> + spec_account_is_not_frozen(@TreasuryCompliance); + + /// resource struct FreezingBit persists + invariant update forall addr: address where old(exists(addr)): exists(addr); + + /// resource struct FreezeEventsHolder is there forever after initialization + invariant [suspendable] DiemTimestamp::is_operating() ==> exists(@DiemRoot); + + /// Only TreasuryCompliance can change the freezing bits of accounts [[H7]][PERMISSION]. + invariant update forall addr: address where old(exists(addr)): + global(addr).is_frozen != old(global(addr).is_frozen) + ==> Roles::spec_signed_by_treasury_compliance_role(); + } + + /// # Helper Functions + spec module { + + fun spec_account_is_frozen(addr: address): bool { + exists(addr) && global(addr).is_frozen + } + + fun spec_account_is_not_frozen(addr: address): bool { + exists(addr) && !global(addr).is_frozen + } + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountLimits.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountLimits.move new file mode 100644 index 000000000..bb86d3ba8 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/AccountLimits.move @@ -0,0 +1,607 @@ +/// Module which manages account limits, like the amount of currency which can flow in or out over +/// a given time period. +module DiemFramework::AccountLimits { + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::errors; + use std::signer; + friend DiemFramework::XDX; + friend DiemFramework::XUS; + + /// An operations capability that restricts callers of this module since + /// the operations can mutate account states. + struct AccountLimitMutationCapability has store { } + + /// A resource specifying the account limits per-currency. There is a default + /// "unlimited" `LimitsDefinition` resource for accounts published at`@DiemRoot`, but other + /// accounts may have different account limit definitons. In such cases, they will have a + /// `LimitsDefinition` published under their (root) account. + struct LimitsDefinition has key { + /// The maximum inflow allowed during the specified time period. + max_inflow: u64, + /// The maximum outflow allowed during the specified time period. + max_outflow: u64, + /// Time period, specified in microseconds + time_period: u64, + /// The maximum amount that can be held + max_holding: u64, + } + spec LimitsDefinition { + invariant max_inflow > 0; + invariant max_outflow > 0; + invariant time_period > 0; + invariant max_holding > 0; + } + + /// A struct holding account transaction information for the time window + /// starting at `window_start` and lasting for the `time_period` specified + /// in the limits definition at `limit_address`. + struct Window has key { + /// Time window start in microseconds + window_start: u64, + /// The inflow during this time window + window_inflow: u64, + /// The inflow during this time window + window_outflow: u64, + /// The balance that this account has held during this time period. + tracked_balance: u64, + /// address storing the LimitsDefinition resource that governs this window + limit_address: address, + } + + /// The `LimitsDefinition` resource is in an invalid state + const ELIMITS_DEFINITION: u64 = 0; + /// The `Window` resource is in an invalid state + const EWINDOW: u64 = 1; + + /// 24 hours in microseconds + const ONE_DAY: u64 = 86400000000; + const MAX_U64: u64 = 18446744073709551615u64; + + /// Grant a capability to call this module. This does not necessarily + /// need to be a unique capability. + public fun grant_mutation_capability(dr_account: &signer): AccountLimitMutationCapability { + DiemTimestamp::assert_genesis(); + Roles::assert_diem_root(dr_account); + AccountLimitMutationCapability{} + } + spec grant_mutation_capability { + include DiemTimestamp::AbortsIfNotGenesis; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + } + + /// Determines if depositing `amount` of `CoinType` coins into the + /// account at `addr` is amenable with their account limits. + /// Returns false if this deposit violates the account limits. + public fun update_deposit_limits( + amount: u64, + addr: address, + _cap: &AccountLimitMutationCapability, + ): bool acquires LimitsDefinition, Window { + assert!(exists>(addr), errors::not_published(EWINDOW)); + can_receive_and_update_window( + amount, + borrow_global_mut>(addr), + ) + } + spec update_deposit_limits { + pragma opaque; + modifies global>(addr); + ensures exists>(addr); + ensures global>(addr).limit_address + == old(global>(addr).limit_address); + include UpdateDepositLimitsAbortsIf; + include CanReceiveEnsures{receiving: global>(addr)}; + } + spec schema UpdateDepositLimitsAbortsIf { + amount: u64; + addr: address; + include AbortsIfNoWindow; + include CanReceiveAbortsIf{receiving: global>(addr)}; + } + spec schema AbortsIfNoWindow { + addr: address; + aborts_if !exists>(addr) with errors::NOT_PUBLISHED; + } + spec fun spec_update_deposit_limits(amount: u64, addr: address): bool { + spec_receiving_limits_ok(global>(addr), amount) + } + + /// Determine if withdrawing `amount` of `CoinType` coins from + /// the account at `addr` would violate the account limits for that account. + /// Returns `false` if this withdrawal violates account limits. + public fun update_withdrawal_limits( + amount: u64, + addr: address, + _cap: &AccountLimitMutationCapability, + ): bool acquires LimitsDefinition, Window { + assert!(exists>(addr), errors::not_published(EWINDOW)); + can_withdraw_and_update_window( + amount, + borrow_global_mut>(addr), + ) + } + spec update_withdrawal_limits { + pragma opaque; + modifies global>(addr); + ensures exists>(addr); + include UpdateWithdrawalLimitsAbortsIf; + include CanWithdrawEnsures{sending: global>(addr)}; + } + spec schema UpdateWithdrawalLimitsAbortsIf { + amount: u64; + addr: address; + include AbortsIfNoWindow; + include CanWithdrawAbortsIf{sending: global>(addr)}; + } + spec fun spec_update_withdrawal_limits(amount: u64, addr: address): bool { + spec_withdrawal_limits_ok(global>(addr), amount) + } + + /// All accounts that could be subject to account limits will have a + /// `Window` for each currency they can hold published at the top level. + /// Root accounts for multi-account entities will hold this resource at + /// their root/parent account. + public fun publish_window( + dr_account: &signer, + to_limit: &signer, + limit_address: address, + ) { + Roles::assert_diem_root(dr_account); + assert!(exists>(limit_address), errors::not_published(ELIMITS_DEFINITION)); + Roles::assert_parent_vasp_or_child_vasp(to_limit); + assert!( + !exists>(signer::address_of(to_limit)), + errors::already_published(EWINDOW) + ); + move_to( + to_limit, + Window { + window_start: current_time(), + window_inflow: 0, + window_outflow: 0, + tracked_balance: 0, + limit_address, + } + ) + } + spec publish_window { + include PublishWindowAbortsIf; + include PublishWindowEnsures; + } + spec schema PublishWindowAbortsIf { + dr_account: signer; + to_limit: signer; + limit_address: address; + /// Only ParentVASP and ChildVASP can have the account limits [[E1]][ROLE][[E2]][ROLE][[E3]][ROLE][[E4]][ROLE][[E5]][ROLE][[E6]][ROLE][[E7]][ROLE]. + include Roles::AbortsIfNotParentVaspOrChildVasp{account: to_limit}; + + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + aborts_if !exists>(limit_address) with errors::NOT_PUBLISHED; + aborts_if exists>(signer::address_of(to_limit)) with errors::ALREADY_PUBLISHED; + } + + spec schema PublishWindowEnsures { + to_limit: signer; + ensures global>(signer::address_of(to_limit)).window_inflow == 0; + ensures global>(signer::address_of(to_limit)).window_outflow == 0; + ensures global>(signer::address_of(to_limit)).tracked_balance == 0; + } + /// Unrestricted limits are represented by setting all fields in the + /// limits definition to `MAX_U64`. Anyone can publish an unrestricted + /// limits since no windows will point to this limits definition unless the + /// TC account, or a caller with access to a `&AccountLimitMutationCapability` points a + /// window to it. Additionally, the TC controls the values held within this + /// resource once it's published. + public(friend) fun publish_unrestricted_limits(publish_account: &signer) { + assert!( + !exists>(signer::address_of(publish_account)), + errors::already_published(ELIMITS_DEFINITION) + ); + move_to( + publish_account, + LimitsDefinition { + max_inflow: MAX_U64, + max_outflow: MAX_U64, + max_holding: MAX_U64, + time_period: ONE_DAY, + } + ) + } + spec publish_unrestricted_limits { + pragma delegate_invariants_to_caller; + include PublishUnrestrictedLimitsAbortsIf; + } + spec schema PublishUnrestrictedLimitsAbortsIf { + publish_account: signer; + aborts_if exists>(signer::address_of(publish_account)) + with errors::ALREADY_PUBLISHED; + } + spec schema PublishUnrestrictedLimitsEnsures { + publish_account: signer; + ensures exists>(signer::address_of(publish_account)); + } + + // #[test_only] + // TODO: remove this comment when the relevant tests in functional and language-e2e testsuites + // are ported to the unit testing framework + public fun publish_unrestricted_limits_for_testing(publish_account: &signer) { + publish_unrestricted_limits(publish_account); + } + spec publish_unrestricted_limits_for_testing { + pragma verify = false; + } + + /// Updates the `LimitsDefinition` resource at `limit_address`. + /// If any of the field arguments is `0` the corresponding field is not updated. + public fun update_limits_definition( + tc_account: &signer, + limit_address: address, + new_max_inflow: u64, + new_max_outflow: u64, + new_max_holding_balance: u64, + new_time_period: u64, + ) acquires LimitsDefinition { + Roles::assert_treasury_compliance(tc_account); + assert!(exists>(limit_address), errors::not_published(ELIMITS_DEFINITION)); + + // As we don't have Optionals for txn scripts, in update_account_limit_definition.move + // we use 0 value to represent a None (ie no update to that variable) + let limits_def = borrow_global_mut>(limit_address); + if (new_max_inflow > 0) { limits_def.max_inflow = new_max_inflow }; + if (new_max_outflow > 0) { limits_def.max_outflow = new_max_outflow }; + if (new_max_holding_balance > 0) { limits_def.max_holding = new_max_holding_balance }; + if (new_time_period > 0) { limits_def.time_period = new_time_period }; + } + spec update_limits_definition { + modifies global>(limit_address); + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + aborts_if !exists>(limit_address) with errors::NOT_PUBLISHED; + ensures exists>(limit_address); + let old_limits_def = global>(limit_address); + let post new_limits_def = global>(limit_address); + ensures new_max_inflow > 0 ==> new_limits_def.max_inflow == new_max_inflow; + ensures new_max_inflow == 0 ==> new_limits_def.max_inflow == old_limits_def.max_inflow; + ensures new_max_outflow > 0 ==> new_limits_def.max_outflow == new_max_outflow; + ensures new_max_outflow == 0 ==> new_limits_def.max_outflow == old_limits_def.max_outflow; + ensures new_max_holding_balance > 0 ==> new_limits_def.max_holding == new_max_holding_balance; + ensures new_max_holding_balance == 0 ==> new_limits_def.max_holding == old_limits_def.max_holding; + ensures new_time_period > 0 ==> new_limits_def.time_period == new_time_period; + ensures new_time_period == 0 ==> new_limits_def.time_period == old_limits_def.time_period; + } + + /// Update either the `tracked_balance` or `limit_address` fields of the + /// `Window` stored under `window_address`. + /// * Since we don't track balances of accounts before they are limited, once + /// they do become limited the approximate balance in `CoinType` held by + /// the entity across all of its accounts will need to be set by the association. + /// if `aggregate_balance` is set to zero the field is not updated. + /// * This updates the `limit_address` in the window resource to a new limits definition at + /// `new_limit_address`. If the `aggregate_balance` needs to be updated + /// but the `limit_address` should remain the same, the current + /// `limit_address` needs to be passed in for `new_limit_address`. + public fun update_window_info( + tc_account: &signer, + window_address: address, + aggregate_balance: u64, + new_limit_address: address, + ) acquires Window { + Roles::assert_treasury_compliance(tc_account); + let window = borrow_global_mut>(window_address); + if (aggregate_balance != 0) { window.tracked_balance = aggregate_balance }; + assert!(exists>(new_limit_address), errors::not_published(ELIMITS_DEFINITION)); + window.limit_address = new_limit_address; + } + spec update_window_info { + modifies global>(window_address); + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + aborts_if !exists>(window_address); + aborts_if !exists>(new_limit_address) with errors::NOT_PUBLISHED; + ensures exists>(window_address); + let old_window = global>(window_address); + let post new_window = global>(window_address); + ensures aggregate_balance != 0 ==> new_window.tracked_balance == aggregate_balance; + ensures aggregate_balance == 0 ==> new_window.tracked_balance == old_window.tracked_balance; + ensures new_window.limit_address == new_limit_address; + ensures new_window.window_start == old_window.window_start; + ensures new_window.window_inflow == old_window.window_inflow; + ensures new_window.window_outflow == old_window.window_outflow; + } + + /////////////////////////////////////////////////////////////////////////// + // Internal utiility functions + /////////////////////////////////////////////////////////////////////////// + + /// If the time window starting at `window.window_start` and lasting for + /// `limits_definition.time_period` has elapsed, resets the window and + /// the inflow and outflow records. + fun reset_window(window: &mut Window, limits_definition: &LimitsDefinition) { + let current_time = DiemTimestamp::now_microseconds(); + assert!(window.window_start <= MAX_U64 - limits_definition.time_period, errors::limit_exceeded(EWINDOW)); + if (current_time > window.window_start + limits_definition.time_period) { + window.window_start = current_time; + window.window_inflow = 0; + window.window_outflow = 0; + } + } + spec reset_window { + pragma opaque; + include ResetWindowAbortsIf; + include ResetWindowEnsures; + } + spec schema ResetWindowAbortsIf { + window: Window; + limits_definition: LimitsDefinition; + include DiemTimestamp::AbortsIfNotOperating; + aborts_if window.window_start + limits_definition.time_period > max_u64() with errors::LIMIT_EXCEEDED; + } + spec schema ResetWindowEnsures { + window: Window; + limits_definition: LimitsDefinition; + ensures window == old(spec_window_reset_with_limits(window, limits_definition)); + } + spec module { + fun spec_window_expired( + window: Window, + limits_definition: LimitsDefinition + ): bool { + DiemTimestamp::spec_now_microseconds() > window.window_start + limits_definition.time_period + } + fun spec_window_reset_with_limits( + window: Window, + limits_definition: LimitsDefinition + ): Window { + if (spec_window_expired(window, limits_definition)) { + Window{ + limit_address: window.limit_address, + tracked_balance: window.tracked_balance, + window_start: DiemTimestamp::spec_now_microseconds(), + window_inflow: 0, + window_outflow: 0 + } + } else { + window + } + } + } + + /// Verify that the receiving account tracked by the `receiving` window + /// can receive `amount` funds without violating requirements + /// specified the `limits_definition` passed in. + /// If the receipt of `amount` doesn't violate the limits `amount` of + /// `CoinType` is recorded as received in the given `receiving` window. + fun can_receive_and_update_window( + amount: u64, + receiving: &mut Window, + ): bool acquires LimitsDefinition { + assert!(exists>(receiving.limit_address), errors::not_published(ELIMITS_DEFINITION)); + let limits_definition = borrow_global>(receiving.limit_address); + // If the limits are unrestricted then don't do any more work. + if (is_unrestricted(limits_definition)) return true; + + reset_window(receiving, limits_definition); + // Check that the inflow is OK + // TODO(wrwg): instead of aborting if the below additions overflow, we should perhaps just have ok false. + assert!(receiving.window_inflow <= MAX_U64 - amount, errors::limit_exceeded(EWINDOW)); + let inflow_ok = (receiving.window_inflow + amount) <= limits_definition.max_inflow; + // Check that the holding after the deposit is OK + assert!(receiving.tracked_balance <= MAX_U64 - amount, errors::limit_exceeded(EWINDOW)); + let holding_ok = (receiving.tracked_balance + amount) <= limits_definition.max_holding; + // The account with `receiving` window can receive the payment so record it. + if (inflow_ok && holding_ok) { + receiving.window_inflow = receiving.window_inflow + amount; + receiving.tracked_balance = receiving.tracked_balance + amount; + }; + inflow_ok && holding_ok + } + spec can_receive_and_update_window { + pragma opaque; + include CanReceiveAbortsIf; + include CanReceiveEnsures; + } + spec schema CanReceiveAbortsIf { + amount: num; + receiving: Window; + aborts_if !exists>(receiving.limit_address) with errors::NOT_PUBLISHED; + include !spec_window_unrestricted(receiving) ==> CanReceiveRestrictedAbortsIf; + } + spec schema CanReceiveRestrictedAbortsIf { + amount: num; + receiving: Window; + include ResetWindowAbortsIf{ + window: receiving, + limits_definition: spec_window_limits(receiving) + }; + aborts_if spec_window_reset(receiving).window_inflow + amount > max_u64() with errors::LIMIT_EXCEEDED; + aborts_if spec_window_reset(receiving).tracked_balance + amount > max_u64() with errors::LIMIT_EXCEEDED; + } + spec schema CanReceiveEnsures { + amount: num; + receiving: Window; + result: bool; + ensures result == spec_receiving_limits_ok(old(receiving), amount); + ensures + if (result && !spec_window_unrestricted(old(receiving))) + receiving == spec_update_inflow(spec_window_reset(old(receiving)), amount) + else + receiving == spec_window_reset(old(receiving)) || receiving == old(receiving); + } + /// Returns the limits associated with this window. + spec fun spec_window_limits(window: Window): LimitsDefinition { + global>(window.limit_address) + } + /// Returns true of the window has unrestricted limits. + spec fun spec_window_unrestricted(window: Window): bool { + spec_is_unrestricted(spec_window_limits(window)) + } + /// Resets wrapping variables of the given window. + spec fun spec_window_reset(window: Window): Window { + spec_window_reset_with_limits(window, spec_window_limits(window)) + } + /// Checks whether receiving limits are satisfied. + spec fun spec_receiving_limits_ok(receiving: Window, amount: u64): bool { + spec_window_unrestricted(receiving) || + spec_window_reset(receiving).window_inflow + amount + <= spec_window_limits(receiving).max_inflow && + spec_window_reset(receiving).tracked_balance + amount + <= spec_window_limits(receiving).max_holding + } + spec fun spec_update_inflow(receiving: Window, amount: u64): Window { + update_field(update_field(receiving, + window_inflow, receiving.window_inflow + amount), + tracked_balance, receiving.tracked_balance + amount) + } + + /// Verify that `amount` can be withdrawn from the account tracked + /// by the `sending` window without violating any limits specified + /// in its `limits_definition`. + /// If the withdrawal of `amount` doesn't violate the limits `amount` of + /// `CoinType` is recorded as withdrawn in the given `sending` window. + fun can_withdraw_and_update_window( + amount: u64, + sending: &mut Window, + ): bool acquires LimitsDefinition { + assert!(exists>(sending.limit_address), errors::not_published(ELIMITS_DEFINITION)); + let limits_definition = borrow_global>(sending.limit_address); + // If the limits are unrestricted then don't do any more work. + if (is_unrestricted(limits_definition)) return true; + + reset_window(sending, limits_definition); + // Check outflow is OK + assert!(sending.window_outflow <= MAX_U64 - amount, errors::limit_exceeded(EWINDOW)); + let outflow_ok = sending.window_outflow + amount <= limits_definition.max_outflow; + // Flow is OK, so record it. + if (outflow_ok) { + sending.window_outflow = sending.window_outflow + amount; + sending.tracked_balance = if (amount >= sending.tracked_balance) 0 + else sending.tracked_balance - amount; + }; + outflow_ok + } + spec can_withdraw_and_update_window { + pragma opaque; + include CanWithdrawAbortsIf; + include CanWithdrawEnsures; + } + spec schema CanWithdrawAbortsIf { + amount: u64; + sending: &mut Window; + aborts_if !exists>(sending.limit_address) with errors::NOT_PUBLISHED; + include !spec_window_unrestricted(sending) ==> CanWithdrawRestrictedAbortsIf; + } + spec schema CanWithdrawRestrictedAbortsIf { + amount: u64; + sending: &mut Window; + include ResetWindowAbortsIf{ + window: sending, + limits_definition: spec_window_limits(sending) + }; + aborts_if spec_window_reset(sending).window_outflow + amount > MAX_U64 with errors::LIMIT_EXCEEDED; + } + spec schema CanWithdrawEnsures { + result: bool; + amount: u64; + sending: &mut Window; + ensures result == spec_withdrawal_limits_ok(old(sending), amount); + ensures + if (result && !spec_window_unrestricted(old(sending))) + sending == spec_update_outflow(spec_window_reset(old(sending)), amount) + else + sending == spec_window_reset(old(sending)) || sending == old(sending); + } + /// Check whether withdrawal limits are satisfied. + spec fun spec_withdrawal_limits_ok(sending: Window, amount: u64): bool { + spec_window_unrestricted(sending) || + spec_window_reset(sending).window_outflow + amount <= spec_window_limits(sending).max_outflow + } + /// Update outflow. + spec fun spec_update_outflow(sending: Window, amount: u64): Window { + update_field(update_field(sending, + window_outflow, sending.window_outflow + amount), + tracked_balance, if (amount >= sending.tracked_balance) 0 + else sending.tracked_balance - amount) + } + + /// Determine whether the `LimitsDefinition` resource has no restrictions. + fun is_unrestricted(limits_def: &LimitsDefinition): bool { + limits_def.max_inflow == MAX_U64 && + limits_def.max_outflow == MAX_U64 && + limits_def.max_holding == MAX_U64 && + limits_def.time_period == ONE_DAY + } + spec is_unrestricted { + pragma opaque; + aborts_if false; + ensures result == spec_is_unrestricted(limits_def); + } + spec module { + /// Checks whether the limits definition is unrestricted. + fun spec_is_unrestricted(limits_def: LimitsDefinition): bool { + limits_def.max_inflow == max_u64() && + limits_def.max_outflow == max_u64() && + limits_def.max_holding == max_u64() && + limits_def.time_period == 86400000000 + } + } + + public fun limits_definition_address(addr: address): address acquires Window { + borrow_global>(addr).limit_address + } + + public fun has_limits_published(addr: address): bool { + exists>(addr) + } + + public fun has_window_published(addr: address): bool { + exists>(addr) + } + spec has_window_published { + ensures result == spec_has_window_published(addr); + } + spec module { + fun spec_has_window_published(addr: address): bool { + exists>(addr) + } + } + + fun current_time(): u64 { + if (DiemTimestamp::is_genesis()) 0 else DiemTimestamp::now_microseconds() + } + + spec current_time(): u64 { + ensures DiemTimestamp::is_genesis() ==> result == 0; + } + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + spec module { + /// `LimitsDefinition` persists after publication. + invariant update + forall addr: address where old(exists>(addr)): + exists>(addr); + + /// `Window` persists after publication + invariant update + forall window_addr: address where old(exists>(window_addr)): + exists>(window_addr); + + /// Invariant that `LimitsDefinition` exists if a `Window` exists. + invariant + forall window_addr: address where exists>(window_addr): + exists>(global>(window_addr).limit_address); + } + + /// # Access Control + + spec module { + /// Only ParentVASP and ChildVASP can have the account limits [[E1]][ROLE][[E2]][ROLE][[E3]][ROLE][[E4]][ROLE][[E5]][ROLE][[E6]][ROLE][[E7]][ROLE]. + invariant + forall addr: address where exists>(addr): + exists(addr) && + (global(addr).role_id == Roles::PARENT_VASP_ROLE_ID || + global(addr).role_id == Roles::CHILD_VASP_ROLE_ID); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Authenticator.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Authenticator.move new file mode 100644 index 000000000..bf683fb28 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Authenticator.move @@ -0,0 +1,108 @@ +/// Move representation of the authenticator types used in Diem. The supported types are Ed25519 (single-sig) +/// and MultiEd25519 (K-of-N multisig). +module DiemFramework::Authenticator { + use std::errors; + use std::hash; + use std::bcs; + use std::vector; + + /// A multi-ed25519 public key + struct MultiEd25519PublicKey has copy, drop, store { + /// vector of ed25519 public keys + public_keys: vector>, + /// approval threshold + threshold: u8, + } + + /// Scheme byte ID for ed25519 + const SINGLE_ED25519_SCHEME_ID: u8 = 0; + /// Scheme byte ID for multi-ed25519 + const MULTI_ED25519_SCHEME_ID: u8 = 1; + + /// Maximum number of keys allowed in a MultiEd25519 public/private key + const MAX_MULTI_ED25519_KEYS: u64 = 32; + + /// Threshold provided was 0 which can't be used to create a `MultiEd25519` key + const EZERO_THRESHOLD: u64 = 0; + /// Not enough keys were provided for the specified threshold when creating an `MultiEd25519` key + const ENOT_ENOUGH_KEYS_FOR_THRESHOLD: u64 = 1; + /// Too many keys were provided for the specified threshold when creating an `MultiEd25519` key + const ENUM_KEYS_ABOVE_MAX_THRESHOLD: u64 = 2; + + /// Create a a multisig policy from a vector of ed25519 public keys and a threshold. + /// Note: this does *not* check uniqueness of keys. Repeated keys are convenient to + /// encode weighted multisig policies. For example Alice AND 1 of Bob or Carol is + /// public_key: {alice_key, alice_key, bob_key, carol_key}, threshold: 3 + /// Aborts if threshold is zero or bigger than the length of `public_keys`. + public fun create_multi_ed25519( + public_keys: vector>, + threshold: u8 + ): MultiEd25519PublicKey { + // check threshold requirements + let len = vector::length(&public_keys); + assert!(threshold != 0, errors::invalid_argument(EZERO_THRESHOLD)); + assert!( + (threshold as u64) <= len, + errors::invalid_argument(ENOT_ENOUGH_KEYS_FOR_THRESHOLD) + ); + // the multied25519 signature scheme allows at most 32 keys + assert!( + len <= MAX_MULTI_ED25519_KEYS, + errors::invalid_argument(ENUM_KEYS_ABOVE_MAX_THRESHOLD) + ); + + MultiEd25519PublicKey { public_keys, threshold } + } + + /// Compute an authentication key for the ed25519 public key `public_key` + public fun ed25519_authentication_key(public_key: vector): vector { + vector::push_back(&mut public_key, SINGLE_ED25519_SCHEME_ID); + hash::sha3_256(public_key) + } + spec ed25519_authentication_key { + pragma opaque = true; + aborts_if false; + ensures [abstract] result == spec_ed25519_authentication_key(public_key); + } + /// We use an uninterpreted function to represent the result of key construction. The actual value + /// does not matter for the verification of callers. + spec fun spec_ed25519_authentication_key(public_key: vector): vector; + + /// Compute a multied25519 account authentication key for the policy `k` + public fun multi_ed25519_authentication_key(k: &MultiEd25519PublicKey): vector { + let public_keys = &k.public_keys; + let len = vector::length(public_keys); + let authentication_key_preimage = vector::empty(); + let i = 0; + while (i < len) { + let public_key = *vector::borrow(public_keys, i); + vector::append( + &mut authentication_key_preimage, + public_key + ); + i = i + 1; + }; + vector::append(&mut authentication_key_preimage, bcs::to_bytes(&k.threshold)); + vector::push_back(&mut authentication_key_preimage, MULTI_ED25519_SCHEME_ID); + hash::sha3_256(authentication_key_preimage) + } + spec multi_ed25519_authentication_key { + pragma opaque; + aborts_if false; + ensures [abstract] result == spec_multi_ed25519_authentication_key(k); + } + /// We use an uninterpreted function to represent the result of key construction. The actual value + /// does not matter for the verification of callers. + spec fun spec_multi_ed25519_authentication_key(k: MultiEd25519PublicKey): vector; + + /// Return the public keys involved in the multisig policy `k` + public fun public_keys(k: &MultiEd25519PublicKey): &vector> { + &k.public_keys + } + + /// Return the threshold for the multisig policy `k` + public fun threshold(k: &MultiEd25519PublicKey): u8 { + *&k.threshold + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/CRSN.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/CRSN.move new file mode 100644 index 000000000..7880280dc --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/CRSN.move @@ -0,0 +1,265 @@ +/// A module implementing conflict-resistant sequence numbers (CRSNs). +/// The specification, and formal description of the acceptance and rejection +/// criteria, force expiration and window shifting of CRSNs are described in DIP-168. + +module DiemFramework::CRSN { + use DiemFramework::Roles; + use std::bit_vector::{Self, BitVector}; + use std::event::{Self, EventHandle}; + use std::signer; + use std::errors; + + friend DiemFramework::DiemAccount; + + /// A CRSN represents a finite slice or window of an "infinite" bitvector + /// starting at zero with a size `k` defined dynamically at the time of + /// publication of CRSN resource. The `min_nonce` defines the left-hand + /// side of the slice, and the slice's state is held in `slots` and is of size `k`. + /// Diagrammatically: + /// ``` + /// 1111...000000100001000000...0100001000000...0000... + /// ^ ... ^ + /// |____..._____slots______...______| + /// min_nonce min_nonce + k - 1 + /// ``` + struct CRSN has key { + min_nonce: u64, + size: u64, + slots: BitVector, + force_shift_events: EventHandle, + } + + /// Whenever a force shift is performed a `ForceShiftEvent` is emitted. + /// This is used to prove the absence of a transaction at a specific sequence nonce. + struct ForceShiftEvent has drop, store { + /// current LHS of the CRSN state + current_min_nonce: u64, + /// The amount the window is being shifted + shift_amount: u64, + /// The state of the bitvector just before the shift. The state of + /// the CRSN's bitvector is needed at the time of the shift to prove + /// that a CRSNs nonce was expired, and not already used by a transaction + /// in the past. This can be used to prove that a transaction can't + /// exist from an account because the slot was expired and not used. + /// Note: the sequence nonce of the shifting transaction will not be set. + bits_at_shift: BitVector, + } + + /// Flag stored in memory to turn on CRSNs + struct CRSNsAllowed has key { } + + /// No CRSN resource exists + const ENO_CRSN: u64 = 0; + /// A CRSN resource wasn't expected, but one was found + const EHAS_CRSN: u64 = 1; + /// The size given to the CRSN at the time of publishing was zero, which is not supported + const EZERO_SIZE_CRSN: u64 = 2; + /// The size given to the CRSN at the time of publishing was larger than the largest allowed CRSN size + const ECRSN_SIZE_TOO_LARGE: u64 = 3; + /// the amount to shift the CRSN window was zero + const EINVALID_SHIFT: u64 = 4; + /// CRSNs are not yet permitted in the network + const ENOT_INITIALIZED: u64 = 5; + /// CRSNs were already initialized + const EALREADY_INITIALIZED: u64 = 6; + + const MAX_CRSN_SIZE: u64 = 256; + + public fun allow_crsns(account: &signer) { + Roles::assert_diem_root(account); + assert!(!exists(signer::address_of(account)), errors::invalid_state(EALREADY_INITIALIZED)); + move_to(account, CRSNsAllowed { }) + } + + /// Publish a DSN under `account`. Cannot already have a DSN published. + public(friend) fun publish(account: &signer, min_nonce: u64, size: u64) { + assert!(!has_crsn(signer::address_of(account)), errors::invalid_state(EHAS_CRSN)); + assert!(size > 0, errors::invalid_argument(EZERO_SIZE_CRSN)); + assert!(size <= MAX_CRSN_SIZE, errors::invalid_argument(ECRSN_SIZE_TOO_LARGE)); + assert!(exists(@DiemRoot), errors::invalid_state(ENOT_INITIALIZED)); + move_to(account, CRSN { + min_nonce, + size, + slots: bit_vector::new(size), + force_shift_events: event::new_event_handle(account), + }) + } + spec publish { + include bit_vector::NewAbortsIf{length: size}; + aborts_if !exists(@DiemRoot) with errors::INVALID_STATE; + aborts_if has_crsn(signer::address_of(account)) with errors::INVALID_STATE; + aborts_if size == 0 with errors::INVALID_ARGUMENT; + aborts_if size > MAX_CRSN_SIZE with errors::INVALID_ARGUMENT; + ensures exists(signer::address_of(account)); + } + + /// Record `sequence_nonce` under the `account`. Returns true if + /// `sequence_nonce` is accepted, returns false if the `sequence_nonce` is rejected. + public(friend) fun record(account: &signer, sequence_nonce: u64): bool + acquires CRSN { + let addr = signer::address_of(account); + if (check(account, sequence_nonce)) { + // CRSN exists by `check`. + let crsn = borrow_global_mut(addr); + // accept nonce + let scaled_nonce = sequence_nonce - crsn.min_nonce; + bit_vector::set(&mut crsn.slots, scaled_nonce); + shift_window_right(crsn); + return true + } else if (exists(addr)) { // window was force shifted in this transaction + let crsn = borrow_global(addr); + if (crsn.min_nonce > sequence_nonce) return true + }; + + false + } + spec record { + pragma opaque; + // TODO: Complete this spec when BitVector (specially its use of loops) + // is completely specified. The behavior of this function is abstracted + // out for now in order to make a progress in verifying the epilogue + // functions in the DiemAccount module. + modifies global(signer::address_of(account)); + aborts_if [abstract] false; + ensures [abstract] result == true; + } + + /// A stateless version of `record`: returns `true` if the `sequence_nonce` + /// will be accepted, and `false` otherwise. + public(friend) fun check(account: &signer, sequence_nonce: u64): bool + acquires CRSN { + let addr = signer::address_of(account); + assert!(has_crsn(addr), errors::invalid_state(ENO_CRSN)); + let crsn = borrow_global_mut(addr); + + // Don't accept if it's outside of the window + if ((sequence_nonce < crsn.min_nonce) || + ((sequence_nonce as u128) >= (crsn.min_nonce as u128) + (bit_vector::length(&crsn.slots) as u128))) { + false + } else { + // scaled nonce is the index in the window + let scaled_nonce = sequence_nonce - crsn.min_nonce; + + // Bit already set, reject, otherwise accept + !bit_vector::is_index_set(&crsn.slots, scaled_nonce) + } + } + spec check { + modifies global(signer::address_of(account)); + include CheckAbortsIf{addr: signer::address_of(account)}; + } + spec schema CheckAbortsIf { + addr: address; + sequence_nonce: u64; + let crsn = global(addr); + let scaled_nonce = sequence_nonce - crsn.min_nonce; + aborts_if !has_crsn(addr) with errors::INVALID_STATE; + include has_crsn(addr) && + (sequence_nonce >= crsn.min_nonce) && + (sequence_nonce + crsn.min_nonce < bit_vector::length(crsn.slots)) + ==> bit_vector::IsIndexSetAbortsIf{bitvector: crsn.slots, bit_index: scaled_nonce }; + } + spec fun spec_check(addr: address, sequence_nonce: u64): bool { + let crsn = global(addr); + if ((sequence_nonce < crsn.min_nonce) || + (sequence_nonce >= crsn.min_nonce + bit_vector::length(crsn.slots))) { + false + } else { + let scaled_nonce = sequence_nonce - crsn.min_nonce; + !bit_vector::spec_is_index_set(crsn.slots, scaled_nonce) + } + } + + /// Force expire transactions by forcibly shifting the window by + /// `shift_amount`. After the window has been shifted by `shift_amount` it is + /// then shifted over set bits as define by the `shift_window_right` function. + public fun force_expire(account: &signer, shift_amount: u64) + acquires CRSN { + assert!(shift_amount > 0, errors::invalid_argument(EINVALID_SHIFT)); + let addr = signer::address_of(account); + assert!(has_crsn(addr), errors::invalid_state(ENO_CRSN)); + let crsn = borrow_global_mut(addr); + + event::emit_event(&mut crsn.force_shift_events, ForceShiftEvent { + current_min_nonce: crsn.min_nonce, + shift_amount: shift_amount, + bits_at_shift: *&crsn.slots, + }); + + bit_vector::shift_left(&mut crsn.slots, shift_amount); + + crsn.min_nonce = crsn.min_nonce + shift_amount; + // shift over any set bits + shift_window_right(crsn); + } + + spec force_expire { + // TODO: this ensures may not hold + // let addr = signer::address_of(account); + // ensures global(addr).min_nonce == old(global(addr)).min_nonce + shift_amount; + } + /// Return whether this address has a CRSN resource published under it. + public fun has_crsn(addr: address): bool { + exists(addr) + } + + fun shift_window_right(crsn: &mut CRSN) { + let index = bit_vector::longest_set_sequence_starting_at(&crsn.slots, 0); + + // if there is no run of set bits return early + if (index == 0) return; + bit_vector::shift_left(&mut crsn.slots, index); + crsn.min_nonce = crsn.min_nonce + index; + } + + + /***************************************************************************/ + // tests + /***************************************************************************/ + + #[test_only] + public fun test_publish(account: &signer, min_nonce: u64, size: u64) { + publish(account, min_nonce, size) + } + + #[test_only] + public fun test_record(account: &signer, sequence_nonce: u64): bool + acquires CRSN { + record(account, sequence_nonce) + } + + #[test_only] + public fun test_check(account: &signer, sequence_nonce: u64): bool + acquires CRSN { + check(account, sequence_nonce) + } + + #[test_only] + public fun test_force_expire(account: &signer, shift_amount: u64) + acquires CRSN { + force_expire(account, shift_amount) + } + + #[test_only] + public fun slots(account: address): BitVector + acquires CRSN { + *&borrow_global(account).slots + } + + #[test_only] + public fun min_nonce(account: address): u64 + acquires CRSN { + *&borrow_global(account).min_nonce + } + + #[test_only] + public fun size(account: address): u64 + acquires CRSN { + *&borrow_global(account).size + } + + #[test_only] + public fun max_crsn_size(): u64 { + MAX_CRSN_SIZE + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ChainId.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ChainId.move new file mode 100644 index 000000000..8d3ba1555 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ChainId.move @@ -0,0 +1,60 @@ +/// The chain id distinguishes between different chains (e.g., testnet and the main Diem network). +/// One important role is to prevent transactions intended for one chain from being executed on another. +/// This code provides a container for storing a chain id and functions to initialize and get it. +module DiemFramework::ChainId { + use DiemFramework::CoreAddresses; + use DiemFramework::DiemTimestamp; + use std::errors; + use std::signer; + + struct ChainId has key { + id: u8 + } + + /// The `ChainId` resource was not in the required state + const ECHAIN_ID: u64 = 0; + + /// Publish the chain ID `id` of this Diem instance under the DiemRoot account + public fun initialize(dr_account: &signer, id: u8) { + DiemTimestamp::assert_genesis(); + CoreAddresses::assert_diem_root(dr_account); + assert!(!exists(signer::address_of(dr_account)), errors::already_published(ECHAIN_ID)); + move_to(dr_account, ChainId { id }) + } + + spec initialize { + pragma opaque; + let dr_addr = signer::address_of(dr_account); + modifies global(dr_addr); + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + aborts_if exists(dr_addr) with errors::ALREADY_PUBLISHED; + ensures exists(dr_addr); + } + + /// Return the chain ID of this Diem instance + public fun get(): u8 acquires ChainId { + DiemTimestamp::assert_operating(); + borrow_global(@DiemRoot).id + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Initialization + + spec module { + /// When Diem is operating, the chain id is always available. + invariant [suspendable] DiemTimestamp::is_operating() ==> exists(@DiemRoot); + + // Could also specify that ChainId is not stored on any other address, but it doesn't matter. + } + + /// # Helper Functions + + spec fun spec_get_chain_id(): u8 { + global(@DiemRoot).id + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/CoreAddresses.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/CoreAddresses.move new file mode 100644 index 000000000..1d79e9fa4 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/CoreAddresses.move @@ -0,0 +1,83 @@ +/// Module providing well-known addresses and related logic. +/// +/// > Note: this module currently defines zero-argument functions like `Self::DIEM_ROOT_ADDRESS()` using capitalization +/// > in the name, following the convention for constants. Eventually, those functions are planned to become actual +/// > global constants, once the Move language supports this feature. +module DiemFramework::CoreAddresses { + use std::errors; + use std::signer; + + /// The operation can only be performed by the account at 0xA550C18 (Diem Root) + const EDIEM_ROOT: u64 = 0; + /// The operation can only be performed by the account at 0xB1E55ED (Treasury & Compliance) + const ETREASURY_COMPLIANCE: u64 = 1; + /// The operation can only be performed by the VM + const EVM: u64 = 2; + /// The operation can only be performed by the account where currencies are registered + const ECURRENCY_INFO: u64 = 3; + + /// Assert that the account is the Diem root address. + public fun assert_diem_root(account: &signer) { + assert!(signer::address_of(account) == @DiemRoot, errors::requires_address(EDIEM_ROOT)) + } + spec assert_diem_root { + pragma opaque; + include AbortsIfNotDiemRoot; + } + + /// Specifies that a function aborts if the account does not have the Diem root address. + spec schema AbortsIfNotDiemRoot { + account: signer; + aborts_if signer::address_of(account) != @DiemRoot with errors::REQUIRES_ADDRESS; + } + + /// Assert that the signer has the treasury compliance address. + public fun assert_treasury_compliance(account: &signer) { + assert!( + signer::address_of(account) == @TreasuryCompliance, + errors::requires_address(ETREASURY_COMPLIANCE) + ) + } + spec assert_treasury_compliance { + pragma opaque; + include AbortsIfNotTreasuryCompliance; + } + + /// Specifies that a function aborts if the account does not have the treasury compliance address. + spec schema AbortsIfNotTreasuryCompliance { + account: signer; + aborts_if signer::address_of(account) != @TreasuryCompliance + with errors::REQUIRES_ADDRESS; + } + + /// Assert that the signer has the VM reserved address. + public fun assert_vm(account: &signer) { + assert!(signer::address_of(account) == @VMReserved, errors::requires_address(EVM)) + } + spec assert_vm { + pragma opaque; + include AbortsIfNotVM; + } + + /// Specifies that a function aborts if the account does not have the VM reserved address. + spec schema AbortsIfNotVM { + account: signer; + aborts_if signer::address_of(account) != @VMReserved with errors::REQUIRES_ADDRESS; + } + + /// Assert that the signer has the currency info address. + public fun assert_currency_info(account: &signer) { + assert!(signer::address_of(account) == @CurrencyInfo, errors::requires_address(ECURRENCY_INFO)) + } + spec assert_currency_info { + pragma opaque; + include AbortsIfNotCurrencyInfo; + } + + /// Specifies that a function aborts if the account has not the currency info address. + spec schema AbortsIfNotCurrencyInfo { + account: signer; + aborts_if signer::address_of(account) != @CurrencyInfo with errors::REQUIRES_ADDRESS; + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DesignatedDealer.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DesignatedDealer.move new file mode 100644 index 000000000..de4fb50b7 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DesignatedDealer.move @@ -0,0 +1,221 @@ +/// Module providing functionality for designated dealers. +module DiemFramework::DesignatedDealer { + use DiemFramework::Diem; + use DiemFramework::Roles; + use DiemFramework::XUS::XUS; + use std::errors; + use std::event; + use std::signer; + friend DiemFramework::DiemAccount; + + /// A `DesignatedDealer` always holds this `Dealer` resource regardless of the + /// currencies it can hold. All `ReceivedMintEvent` events for all + /// currencies will be emitted on `mint_event_handle`. + struct Dealer has key { + /// Handle for mint events + mint_event_handle: event::EventHandle, + } + + spec schema AbortsIfNoDealer { + dd_addr: address; + aborts_if !exists(dd_addr) with errors::NOT_PUBLISHED; + } + + /// The `TierInfo` resource holds the information needed to track which + /// tier a mint to a DD needs to be in. + /// DEPRECATED: This resource is no longer used and will be removed from the system + // PreburnQueue published at top level in Diem.move + struct TierInfo has key { + /// Time window start in microseconds + window_start: u64, + /// The minted inflow during this time window + window_inflow: u64, + /// 0-indexed array of tier upperbounds + tiers: vector, + } + + /// Message for mint events + struct ReceivedMintEvent has drop, store { + /// The currency minted + currency_code: vector, + /// The address that receives the mint + destination_address: address, + /// The amount minted (in base units of `currency_code`) + amount: u64, + } + + /// The `DesignatedDealer` resource is in an invalid state + const EDEALER: u64 = 0; + // Error codes 1 -- 3 were deprecated along with tiered minting in Diem Framework version 2 + // const EINVALID_TIER_ADDITION: u64 = 1; + // const EINVALID_TIER_START: u64 = 2; + // const EINVALID_TIER_INDEX: u64 = 3; + /// A zero mint amount was provided + const EINVALID_MINT_AMOUNT: u64 = 4; + + /////////////////////////////////////////////////////////////////////////// + // To-be designated-dealer called functions + /////////////////////////////////////////////////////////////////////////// + + /// Publishes a `Dealer` resource under `dd` with a `PreburnQueue`. + /// If `add_all_currencies = true` this will add a `PreburnQueue`, + /// for each known currency at launch. + public(friend) fun publish_designated_dealer_credential( + dd: &signer, + tc_account: &signer, + add_all_currencies: bool, + ){ + Roles::assert_treasury_compliance(tc_account); + Roles::assert_designated_dealer(dd); + assert!(!exists(signer::address_of(dd)), errors::already_published(EDEALER)); + move_to(dd, Dealer { mint_event_handle: event::new_event_handle(dd) }); + if (add_all_currencies) { + add_currency(dd, tc_account); + } else { + add_currency(dd, tc_account); + }; + } + spec publish_designated_dealer_credential { + pragma opaque; + + let dd_addr = signer::address_of(dd); + + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include Roles::AbortsIfNotDesignatedDealer{account: dd}; + aborts_if exists(dd_addr) with errors::ALREADY_PUBLISHED; + include if (add_all_currencies) AddCurrencyAbortsIf{dd_addr: dd_addr} + else AddCurrencyAbortsIf{dd_addr: dd_addr}; + + modifies global(dd_addr); + ensures exists(dd_addr); + modifies global(dd_addr); + modifies global>(dd_addr); + modifies global>(dd_addr); + } + + /////////////////////////////////////////////////////////////////////////// + // Publicly callable APIs by Treasury Compliance Account + /////////////////////////////////////////////////////////////////////////// + + /// Adds the needed resources to the DD account `dd` in order to work with `CoinType`. + /// Public so that a currency can be added to a DD later on. Will require + /// multi-signer transactions in order to add a new currency to an existing DD. + public(friend) fun add_currency(dd: &signer, tc_account: &signer) { + Roles::assert_treasury_compliance(tc_account); + let dd_addr = signer::address_of(dd); + assert!(exists_at(dd_addr), errors::not_published(EDEALER)); + Diem::publish_preburn_queue_to_account(dd, tc_account); + } + // #[test_only] TODO: uncomment once unit tests are fully migrated + public fun add_currency_for_test(dd: &signer, tc_account: &signer) { + add_currency(dd, tc_account) + } + spec add_currency { + pragma opaque; + + let dd_addr = signer::address_of(dd); + + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include Roles::AbortsIfNotDesignatedDealer{account: dd}; + include AbortsIfNoDealer{dd_addr: dd_addr}; + include AddCurrencyAbortsIf{dd_addr: dd_addr}; + + modifies global>(dd_addr); + } + spec schema AddCurrencyAbortsIf { + dd_addr: address; + include Diem::AbortsIfNoCurrency; + aborts_if Diem::is_synthetic_currency() with errors::INVALID_ARGUMENT; + aborts_if exists>(dd_addr) with errors::ALREADY_PUBLISHED; + aborts_if exists>(dd_addr) with errors::INVALID_STATE; + } + + public fun tiered_mint( + tc_account: &signer, + amount: u64, + dd_addr: address, + // tiers are deprecated. We continue to accept this argument for backward + // compatibility, but it will be ignored. + _tier_index: u64, + ): Diem::Diem acquires Dealer, TierInfo { + Roles::assert_treasury_compliance(tc_account); + assert!(amount > 0, errors::invalid_argument(EINVALID_MINT_AMOUNT)); + assert!(exists_at(dd_addr), errors::not_published(EDEALER)); + + // Delete deprecated `TierInfo` resources. + // TODO: delete this code once there are no more TierInfo resources in the system + if (exists>(dd_addr)) { + let TierInfo { window_start: _, window_inflow: _, tiers: _ } = move_from>(dd_addr); + }; + + // Send ReceivedMintEvent + event::emit_event( + &mut borrow_global_mut(dd_addr).mint_event_handle, + ReceivedMintEvent { + currency_code: Diem::currency_code(), + destination_address: dd_addr, + amount + }, + ); + Diem::mint(tc_account, amount) + } + spec tiered_mint { + pragma opaque; + + include TieredMintAbortsIf; + include TieredMintEmits; + + modifies global(dd_addr); + ensures exists(dd_addr); + modifies global>(@CurrencyInfo); + ensures exists>(@CurrencyInfo); + modifies global>(dd_addr); + ensures !exists>(dd_addr); + let currency_info = global>(@CurrencyInfo); + let post post_currency_info = global>(@CurrencyInfo); + ensures result.value == amount; + ensures post_currency_info == update_field(currency_info, total_value, currency_info.total_value + amount); + } + spec schema TieredMintAbortsIf { + tc_account: signer; + dd_addr: address; + amount: u64; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + aborts_if amount == 0 with errors::INVALID_ARGUMENT; + include AbortsIfNoDealer; + aborts_if !exists>(signer::address_of(tc_account)) with errors::REQUIRES_CAPABILITY; + include Diem::MintAbortsIf{value: amount}; + } + spec schema TieredMintEmits { + dd_addr: address; + amount: u64; + let handle = global(dd_addr).mint_event_handle; + let msg = ReceivedMintEvent { + currency_code: Diem::spec_currency_code(), + destination_address: dd_addr, + amount, + }; + emits msg to handle; + include Diem::MintEmits{value: amount}; + } + + public fun exists_at(dd_addr: address): bool { + exists(dd_addr) + } + spec exists_at { + pragma opaque; + aborts_if false; + ensures result == exists(dd_addr); + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + spec module { + /// resource struct Dealer persists after publication + invariant update forall addr: address where old(exists(addr)): exists(addr); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Diem.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Diem.move new file mode 100644 index 000000000..9681b7562 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Diem.move @@ -0,0 +1,1940 @@ +/// The `Diem` module describes the concept of a coin in the Diem framework. It introduces the +/// resource `Diem::Diem`, representing a coin of given coin type. +/// The module defines functions operating on coins as well as functionality like +/// minting and burning of coins. +module DiemFramework::Diem { + use DiemFramework::CoreAddresses; + use DiemFramework::RegisteredCurrencies; + use DiemFramework::Roles; + use DiemFramework::DiemTimestamp; + use std::errors; + use std::event::{Self, EventHandle}; + use std::fixed_point32::{Self, FixedPoint32}; + use std::signer; + use std::vector; + + friend DiemFramework::DesignatedDealer; + friend DiemFramework::XDX; + friend DiemFramework::TransactionFee; + + /// The `Diem` resource defines the Diem coin for each currency in + /// Diem. Each "coin" is coupled with a type `CoinType` specifying the + /// currency of the coin, and a `value` field specifying the value + /// of the coin (in the base units of the currency `CoinType` + /// and specified in the `CurrencyInfo` resource for that `CoinType` + /// published under the `@CurrencyInfo` account address). + struct Diem has store { + /// The value of this coin in the base units for `CoinType` + value: u64 + } + + /// The `MintCapability` resource defines a capability to allow minting + /// of coins of `CoinType` currency by the holder of this capability. + /// This capability is held only either by the `@TreasuryCompliance` + /// account or the `DiemFramework::XDX` module (and `@DiemRoot` in testnet). + struct MintCapability has key, store { } + + /// The `BurnCapability` resource defines a capability to allow coins + /// of `CoinType` currency to be burned by the holder of it. + struct BurnCapability has key, store { } + + /// A `MintEvent` is emitted every time a Diem coin is minted. This + /// contains the `amount` minted (in base units of the currency being + /// minted) along with the `currency_code` for the coin(s) being + /// minted, and that is defined in the `currency_code` field of the + /// `CurrencyInfo` resource for the currency. + struct MintEvent has drop, store { + /// Funds added to the system + amount: u64, + /// ASCII encoded symbol for the coin type (e.g., "XDX") + currency_code: vector, + } + + /// A `BurnEvent` is emitted every time a non-synthetic Diem coin + /// (i.e., a Diem coin with false `is_synthetic` field) is + /// burned. It contains the `amount` burned in base units for the + /// currency, along with the `currency_code` for the coins being burned + /// (and as defined in the `CurrencyInfo` resource for that currency). + /// It also contains the `preburn_address` from which the coin is + /// extracted for burning. + struct BurnEvent has drop, store { + /// Funds removed from the system + amount: u64, + /// ASCII encoded symbol for the coin type (e.g., "XDX") + currency_code: vector, + /// Address with the `PreburnQueue` resource that stored the now-burned funds + preburn_address: address, + } + + /// A `PreburnEvent` is emitted every time an `amount` of funds with + /// a coin type `currency_code` is enqueued in the `PreburnQueue` resource under + /// the account at the address `preburn_address`. + struct PreburnEvent has drop, store { + /// The amount of funds waiting to be removed (burned) from the system + amount: u64, + /// ASCII encoded symbol for the coin type (e.g., "XDX") + currency_code: vector, + /// Address with the `PreburnQueue` resource that now holds the funds + preburn_address: address, + } + + /// A `CancelBurnEvent` is emitted every time funds of `amount` in a `Preburn` + /// resource held in a `PreburnQueue` at `preburn_address` is canceled (removed from the + /// preburn queue, but not burned). The currency of the funds is given by the + /// `currency_code` as defined in the `CurrencyInfo` for that currency. + struct CancelBurnEvent has drop, store { + /// The amount of funds returned + amount: u64, + /// ASCII encoded symbol for the coin type (e.g., "XDX") + currency_code: vector, + /// Address of the `PreburnQueue` resource that held the now-returned funds. + preburn_address: address, + } + + /// An `ToXDXExchangeRateUpdateEvent` is emitted every time the to-XDX exchange + /// rate for the currency given by `currency_code` is updated. + struct ToXDXExchangeRateUpdateEvent has drop, store { + /// The currency code of the currency whose exchange rate was updated. + currency_code: vector, + /// The new on-chain to-XDX exchange rate between the + /// `currency_code` currency and XDX. Represented in conversion + /// between the (on-chain) base-units for the currency and microdiem. + new_to_xdx_exchange_rate: u64, + } + + /// The `CurrencyInfo` resource stores the various + /// pieces of information needed for a currency (`CoinType`) that is + /// registered on-chain. This resource _must_ be published under the + /// address given by `@CurrencyInfo` in order for the registration of + /// `CoinType` as a recognized currency on-chain to be successful. At + /// the time of registration, the `MintCapability` and + /// `BurnCapability` capabilities are returned to the caller. + /// Unless they are specified otherwise the fields in this resource are immutable. + struct CurrencyInfo has key { + /// The total value for the currency represented by `CoinType`. Mutable. + total_value: u128, + /// Value of funds that are in the process of being burned. Mutable. + preburn_value: u64, + /// The (rough) exchange rate from `CoinType` to `XDX`. Mutable. + to_xdx_exchange_rate: FixedPoint32, + /// Holds whether or not this currency is synthetic (contributes to the + /// off-chain reserve) or not. An example of such a synthetic + ///currency would be the XDX. + is_synthetic: bool, + /// The scaling factor for the coin (i.e. the amount to divide by + /// to get to the human-readable representation for this currency). + /// e.g. 10^6 for `XUS` + scaling_factor: u64, + /// The smallest fractional part (number of decimal places) to be + /// used in the human-readable representation for the currency (e.g. + /// 10^2 for `XUS` cents) + fractional_part: u64, + /// The code symbol for this `CoinType`. ASCII encoded. + /// e.g. for "XDX" this is x"584458". No character limit. + currency_code: vector, + /// Minting of new currency of CoinType is allowed only if this field is true. + /// We may want to disable the ability to mint further coins of a + /// currency while that currency is still around. This allows us to + /// keep the currency in circulation while disallowing further + /// creation of coins in the `CoinType` currency. Mutable. + can_mint: bool, + /// Event stream for minting and where `MintEvent`s will be emitted. + mint_events: EventHandle, + /// Event stream for burning, and where `BurnEvent`s will be emitted. + burn_events: EventHandle, + /// Event stream for preburn requests, and where all + /// `PreburnEvent`s for this `CoinType` will be emitted. + preburn_events: EventHandle, + /// Event stream for all cancelled preburn requests for this + /// `CoinType`. + cancel_burn_events: EventHandle, + /// Event stream for emiting exchange rate change events + exchange_rate_update_events: EventHandle, + } + + /// The maximum value for `CurrencyInfo.scaling_factor` + const MAX_SCALING_FACTOR: u64 = 10000000000; + + /// Data structure invariant for CurrencyInfo. Asserts that `CurrencyInfo.scaling_factor` + /// is always greater than 0 and not greater than `MAX_SCALING_FACTOR` + spec CurrencyInfo { + invariant 0 < scaling_factor && scaling_factor <= MAX_SCALING_FACTOR; + } + + /// A holding area where funds that will subsequently be burned wait while their underlying + /// assets are moved off-chain. + /// This resource can only be created by the holder of a `BurnCapability` + /// or during an upgrade process to the `PreburnQueue` by a designated + /// dealer. An account that contains this address has the authority to + /// initiate a burn request. A burn request can be resolved by the holder + /// of a `BurnCapability` by either (1) burning the funds, or (2) returning + /// the funds to the account that initiated the burn request. + struct Preburn has key, store { + /// A single pending burn amount. This is an element in the + /// `PreburnQueue` resource published under each Designated Dealer account. + to_burn: Diem, + } + + /// A preburn request, along with (an opaque to Move) metadata that is + /// associated with the preburn request. + struct PreburnWithMetadata has store { + preburn: Preburn, + metadata: vector, + } + + /// A queue of preburn requests. This is a FIFO queue whose elements + /// are indexed by the value held within each preburn resource in the + /// `preburns` field. When burning or cancelling a burn of a given + /// `amount`, the `Preburn` resource with with the smallest index in this + /// queue matching `amount` in its `to_burn` coin's `value` field will be + /// removed and its contents either (1) burned, or (2) returned + /// back to the holding DD's account balance. Every `Preburn` resource in + /// the `PreburnQueue` must have a nonzero coin value within it. + /// This resource can be created by either the TreasuryCompliance + /// account, or during the upgrade process, by a designated dealer with an + /// existing `Preburn` resource in `CoinType` + struct PreburnQueue has key { + /// The queue of preburn requests + preburns: vector>, + } + + spec PreburnQueue { + /// The number of outstanding preburn requests is bounded. + invariant len(preburns) <= MAX_OUTSTANDING_PREBURNS; + /// No preburn request can have a zero value. + /// The `value` field of any coin in a `Preburn` resource + /// within this field must be nonzero. + invariant forall i in 0..len(preburns): preburns[i].preburn.to_burn.value > 0; + } + + /// Maximum u64 value. + const MAX_U64: u64 = 18446744073709551615; + /// Maximum u128 value. + const MAX_U128: u128 = 340282366920938463463374607431768211455; + + /// A `BurnCapability` resource is in an unexpected state. + const EBURN_CAPABILITY: u64 = 0; + /// A property expected of a `CurrencyInfo` resource didn't hold + const ECURRENCY_INFO: u64 = 1; + /// A property expected of a `Preburn` resource didn't hold + const EPREBURN: u64 = 2; + /// The preburn slot is already occupied with coins to be burned. + const EPREBURN_OCCUPIED: u64 = 3; + /// A burn was attempted on `Preburn` resource that cointained no coins + const EPREBURN_EMPTY: u64 = 4; + /// Minting is not allowed for the specified currency + const EMINTING_NOT_ALLOWED: u64 = 5; + /// The currency specified is a synthetic (non-fiat) currency + const EIS_SYNTHETIC_CURRENCY: u64 = 6; + /// A property expected of the coin provided didn't hold + const ECOIN: u64 = 7; + /// The destruction of a non-zero coin was attempted. Non-zero coins must be burned. + const EDESTRUCTION_OF_NONZERO_COIN: u64 = 8; + /// A property expected of `MintCapability` didn't hold + const EMINT_CAPABILITY: u64 = 9; + /// A withdrawal greater than the value of the coin was attempted. + const EAMOUNT_EXCEEDS_COIN_VALUE: u64 = 10; + /// A property expected of the `PreburnQueue` resource didn't hold. + const EPREBURN_QUEUE: u64 = 11; + /// A preburn with a matching amount in the preburn queue was not found. + const EPREBURN_NOT_FOUND: u64 = 12; + + /// The maximum number of preburn requests that can be outstanding for a + /// given designated dealer/currency. + const MAX_OUTSTANDING_PREBURNS: u64 = 256; + + /// Initialization of the `Diem` module. Initializes the set of + /// registered currencies in the `DiemFramework::RegisteredCurrencies` on-chain + /// config, and publishes the `CurrencyRegistrationCapability` under the + /// `@DiemRoot`. This can only be called from genesis. + public fun initialize( + dr_account: &signer, + ) { + DiemTimestamp::assert_genesis(); + // Operational constraint + CoreAddresses::assert_diem_root(dr_account); + RegisteredCurrencies::initialize(dr_account); + } + spec initialize { + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + include RegisteredCurrencies::InitializeAbortsIf; + include RegisteredCurrencies::InitializeEnsures; + } + + /// Publishes the `BurnCapability` `cap` for the `CoinType` currency under `account`. `CoinType` + /// must be a registered currency type. The caller must pass a treasury compliance account. + public(friend) fun publish_burn_capability( + tc_account: &signer, + cap: BurnCapability, + ) { + Roles::assert_treasury_compliance(tc_account); + assert_is_currency(); + assert!( + !exists>(signer::address_of(tc_account)), + errors::already_published(EBURN_CAPABILITY) + ); + move_to(tc_account, cap) + } + spec publish_burn_capability { + pragma delegate_invariants_to_caller; + aborts_if !spec_is_currency(); + include PublishBurnCapAbortsIfs; + } + spec schema PublishBurnCapAbortsIfs { + tc_account: &signer; + /// Must abort if tc_account does not have the TreasuryCompliance role. + /// Only a TreasuryCompliance account can have the BurnCapability [[H3]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + aborts_if exists>(signer::address_of(tc_account)) with errors::ALREADY_PUBLISHED; + } + spec schema PublishBurnCapEnsures { + tc_account: &signer; + ensures exists>(signer::address_of(tc_account)); + } + + /// Mints `amount` of currency. The `account` must hold a + /// `MintCapability` at the top-level in order for this call + /// to be successful. + public fun mint(account: &signer, value: u64): Diem + acquires CurrencyInfo, MintCapability { + let addr = signer::address_of(account); + assert!(exists>(addr), errors::requires_capability(EMINT_CAPABILITY)); + mint_with_capability( + value, + borrow_global>(addr) + ) + } + spec mint { + modifies global>(@CurrencyInfo); + ensures exists>(@CurrencyInfo); + /// Must abort if the account does not have the MintCapability [[H1]][PERMISSION]. + aborts_if !exists>(signer::address_of(account)) with errors::REQUIRES_CAPABILITY; + + include MintAbortsIf; + include MintEnsures; + } + + /// Burns the coins held in the first `Preburn` request in the `PreburnQueue` + /// resource held under `preburn_address` that is equal to `amount`. + /// Calls to this functions will fail if the `account` does not have a + /// published `BurnCapability` for the `CoinType` published under it, or if + /// there is not a `Preburn` request in the `PreburnQueue` that does not + /// equal `amount`. + public fun burn( + account: &signer, + preburn_address: address, + amount: u64, + ) acquires BurnCapability, CurrencyInfo, PreburnQueue { + let addr = signer::address_of(account); + assert!(exists>(addr), errors::requires_capability(EBURN_CAPABILITY)); + burn_with_capability( + preburn_address, + borrow_global>(addr), + amount + ) + } + spec burn { + include BurnAbortsIf; + include BurnEnsures; + include BurnWithResourceCapEmits{preburn: spec_make_preburn(amount)}; + } + spec schema BurnAbortsIf { + account: signer; + preburn_address: address; + + /// Must abort if the account does not have the BurnCapability [[H3]][PERMISSION]. + aborts_if !exists>(signer::address_of(account)) with errors::REQUIRES_CAPABILITY; + include BurnWithCapabilityAbortsIf; + } + spec schema BurnEnsures { + account: signer; + preburn_address: address; + include BurnWithCapabilityEnsures; + } + spec schema AbortsIfNoPreburnQueue { + preburn_address: address; + aborts_if !exists>(preburn_address) with errors::NOT_PUBLISHED; + } + + /// Cancels the `Preburn` request in the `PreburnQueue` resource held + /// under the `preburn_address` with a value equal to `amount`, and returns the coins. + /// Calls to this will fail if the sender does not have a published + /// `BurnCapability`, or if there is no preburn request + /// outstanding in the `PreburnQueue` resource under `preburn_address` with + /// a value equal to `amount`. + public fun cancel_burn( + account: &signer, + preburn_address: address, + amount: u64, + ): Diem acquires BurnCapability, CurrencyInfo, PreburnQueue { + assert_is_currency(); + let addr = signer::address_of(account); + assert!(exists>(addr), errors::requires_capability(EBURN_CAPABILITY)); + cancel_burn_with_capability( + preburn_address, + borrow_global>(addr), + amount, + ) + } + spec cancel_burn { + let currency_info = global>(@CurrencyInfo); + let post post_currency_info = global>(@CurrencyInfo); + modifies global>(preburn_address); + modifies global>(@CurrencyInfo); + include CancelBurnAbortsIf; + include CancelBurnWithCapEnsures; + include CancelBurnWithCapEmits; + ensures exists>(@CurrencyInfo); + ensures exists>(preburn_address); + ensures post_currency_info == update_field( + currency_info, + preburn_value, + post_currency_info.preburn_value + ); + ensures result.value == amount; + ensures result.value > 0; + } + + spec schema CancelBurnAbortsIf { + account: signer; + preburn_address: address; + amount: u64; + /// Must abort if the account does not have the BurnCapability [[H3]][PERMISSION]. + aborts_if !exists>(signer::address_of(account)) with errors::REQUIRES_CAPABILITY; + include CancelBurnWithCapAbortsIf; + } + + + /// Mint a new `Diem` coin of `CoinType` currency worth `value`. The + /// caller must have a reference to a `MintCapability`. Only + /// the treasury compliance account or the `DiemFramework::XDX` module can acquire such a + /// reference. + public(friend) fun mint_with_capability( + value: u64, + _capability: &MintCapability + ): Diem acquires CurrencyInfo { + assert_is_currency(); + let currency_code = currency_code(); + // update market cap resource to reflect minting + let info = borrow_global_mut>(@CurrencyInfo); + assert!(info.can_mint, errors::invalid_state(EMINTING_NOT_ALLOWED)); + assert!(MAX_U128 - info.total_value >= (value as u128), errors::limit_exceeded(ECURRENCY_INFO)); + info.total_value = info.total_value + (value as u128); + // don't emit mint events for synthetic currenices as this does not + // change the total value of fiat currencies held on-chain. + if (!info.is_synthetic) { + event::emit_event( + &mut info.mint_events, + MintEvent{ + amount: value, + currency_code, + } + ); + }; + + Diem { value } + } + spec mint_with_capability { + pragma opaque; + pragma delegate_invariants_to_caller; + modifies global>(@CurrencyInfo); + ensures exists>(@CurrencyInfo); + include MintAbortsIf; + include MintEnsures; + include MintEmits; + } + spec schema MintAbortsIf { + value: u64; + include AbortsIfNoCurrency; + aborts_if !spec_currency_info().can_mint with errors::INVALID_STATE; + aborts_if spec_currency_info().total_value + value > max_u128() with errors::LIMIT_EXCEEDED; + } + spec schema MintEnsures { + value: u64; + result: Diem; + let currency_info = global>(@CurrencyInfo); + let post post_currency_info = global>(@CurrencyInfo); + ensures exists>(@CurrencyInfo); + ensures post_currency_info == update_field(currency_info, total_value, currency_info.total_value + value); + ensures result.value == value; + } + spec schema MintEmits { + value: u64; + let currency_info = global>(@CurrencyInfo); + let handle = currency_info.mint_events; + let msg = MintEvent{ + amount: value, + currency_code: currency_info.currency_code, + }; + emits msg to handle if !currency_info.is_synthetic; + } + + /// Add the `coin` to the `preburn.to_burn` field in the `Preburn` resource + /// held in the preburn queue at the address `preburn_address` if it is + /// empty, otherwise raise a `EPREBURN_OCCUPIED` Error. Emits a + /// `PreburnEvent` to the `preburn_events` event stream in the + /// `CurrencyInfo` for the `CoinType` passed in. However, if the currency + /// being preburned is a synthetic currency (`is_synthetic = true`) then no + /// `PreburnEvent` will be emitted. + fun preburn_with_resource( + coin: Diem, + preburn: &mut Preburn, + preburn_address: address, + ) acquires CurrencyInfo { + let coin_value = value(&coin); + // Throw if already occupied + assert!(value(&preburn.to_burn) == 0, errors::invalid_state(EPREBURN_OCCUPIED)); + deposit(&mut preburn.to_burn, coin); + let currency_code = currency_code(); + let info = borrow_global_mut>(@CurrencyInfo); + assert!(MAX_U64 - info.preburn_value >= coin_value, errors::limit_exceeded(ECOIN)); + info.preburn_value = info.preburn_value + coin_value; + // don't emit preburn events for synthetic currenices as this does not + // change the total value of fiat currencies held on-chain, and + // therefore no off-chain movement of the backing coins needs to be + // performed. + if (!info.is_synthetic) { + event::emit_event( + &mut info.preburn_events, + PreburnEvent{ + amount: coin_value, + currency_code, + preburn_address, + } + ); + }; + } + spec preburn_with_resource { + pragma delegate_invariants_to_caller; + modifies global>(@CurrencyInfo); + ensures exists>(@CurrencyInfo); + include PreburnWithResourceAbortsIf{amount: coin.value}; + include PreburnEnsures{amount: coin.value}; + include PreburnWithResourceEmits{amount: coin.value}; + } + spec schema PreburnWithResourceAbortsIf { + amount: u64; + preburn: Preburn; + aborts_if preburn.to_burn.value > 0 with errors::INVALID_STATE; + include PreburnAbortsIf; + } + spec schema PreburnAbortsIf { + amount: u64; + include AbortsIfNoCurrency; + aborts_if spec_currency_info().preburn_value + amount > MAX_U64 with errors::LIMIT_EXCEEDED; + } + spec schema PreburnEnsures { + amount: u64; + preburn: Preburn; + let info = spec_currency_info(); + let post post_info = spec_currency_info(); + ensures post_info == update_field(info, preburn_value, info.preburn_value + amount); + } + spec schema PreburnWithResourceEmits { + amount: u64; + preburn_address: address; + let info = spec_currency_info(); + let currency_code = spec_currency_code(); + let handle = info.preburn_events; + let msg = PreburnEvent { + amount, + currency_code, + preburn_address, + }; + emits msg to handle if !info.is_synthetic; + } + + /////////////////////////////////////////////////////////////////////////// + // Treasury Compliance specific methods for DDs + /////////////////////////////////////////////////////////////////////////// + + /// Create a `Preburn` resource. + /// This is useful for places where a module needs to be able to burn coins + /// outside of a Designated Dealer, e.g., for transaction fees, or for the XDX reserve. + public fun create_preburn( + tc_account: &signer + ): Preburn { + Roles::assert_treasury_compliance(tc_account); + assert_is_currency(); + Preburn { to_burn: zero() } + } + spec create_preburn { + include CreatePreburnAbortsIf; + } + spec schema CreatePreburnAbortsIf { + tc_account: signer; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include AbortsIfNoCurrency; + } + + /// Publish an empty `PreburnQueue` resource under the Designated Dealer + /// dealer account `account`. + fun publish_preburn_queue( + account: &signer + ) { + let account_addr = signer::address_of(account); + Roles::assert_designated_dealer(account); + assert_is_currency(); + assert!( + !exists>(account_addr), + errors::invalid_state(EPREBURN) + ); + assert!( + !exists>(account_addr), + errors::already_published(EPREBURN_QUEUE) + ); + move_to(account, PreburnQueue { + preburns: vector::empty() + }) + } + spec publish_preburn_queue { + pragma opaque; + let account_addr = signer::address_of(account); + modifies global>(account_addr); + // the preburn queue cannot already exist + aborts_if exists>(account_addr) with errors::ALREADY_PUBLISHED; + // There cannot be a preburn resource published at the same time as a + // `PreburnQueue` resource of the same currency. + aborts_if exists>(account_addr) with errors::INVALID_STATE; + include PublishPreburnQueueAbortsIf; + include PublishPreburnQueueEnsures; + } + spec schema PublishPreburnQueueAbortsIf { + account: signer; + include Roles::AbortsIfNotDesignatedDealer; + include AbortsIfNoCurrency; + } + spec schema PublishPreburnQueueEnsures { + account: signer; + let account_addr = signer::address_of(account); + // The preburn queue is published at the end of this function, + ensures exists>(account_addr); + // there cannot be a preburn resource for the same currency as the account, + ensures !exists>(account_addr); + // and the preburn queue is empty + ensures vector::length(global>(account_addr).preburns) == 0; + } + + /// Publish a `Preburn` resource under `account`. This function is + /// used for bootstrapping the designated dealer at account-creation + /// time, and the association TC account `tc_account` (at `@TreasuryCompliance`) is creating + /// this resource for the designated dealer `account`. + public(friend) fun publish_preburn_queue_to_account( + account: &signer, + tc_account: &signer + ) acquires CurrencyInfo { + Roles::assert_designated_dealer(account); + Roles::assert_treasury_compliance(tc_account); + assert!(!is_synthetic_currency(), errors::invalid_argument(EIS_SYNTHETIC_CURRENCY)); + publish_preburn_queue(account) + } + spec publish_preburn_queue_to_account { + pragma opaque; + let account_addr = signer::address_of(account); + modifies global>(account_addr); + /// The premission "PreburnCurrency" is granted to DesignatedDealer [[H4]][PERMISSION]. + /// Must abort if the account does not have the DesignatedDealer role. + include Roles::AbortsIfNotDesignatedDealer; + /// PreburnQueue is published under the DesignatedDealer account. + include PublishPreburnQueueAbortsIf; + include PublishPreburnQueueEnsures; + ensures exists>(account_addr); + + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include AbortsIfNoCurrency; + aborts_if is_synthetic_currency() with errors::INVALID_ARGUMENT; + aborts_if exists>(account_addr) with errors::ALREADY_PUBLISHED; + aborts_if exists>(account_addr) with errors::INVALID_STATE; + + } + + // #[test_only] TODO: uncomment once unit tests are fully migrated + public fun publish_preburn_queue_to_account_for_test( + account: &signer, + tc_account: &signer + ) acquires CurrencyInfo { + publish_preburn_queue_to_account(account, tc_account) + } + spec publish_preburn_queue_to_account_for_test { + pragma verify = false; + } + + + /////////////////////////////////////////////////////////////////////////// + + + /// Upgrade a designated dealer account from using a single `Preburn` + /// resource to using a `PreburnQueue` resource so that multiple preburn + /// requests can be outstanding in the same currency for a designated dealer. + fun upgrade_preburn(account: &signer) + acquires Preburn, PreburnQueue { + Roles::assert_designated_dealer(account); + let sender = signer::address_of(account); + let preburn_exists = exists>(sender); + let preburn_queue_exists = exists>(sender); + // The DD must already have an existing `Preburn` resource, and not a + // `PreburnQueue` resource already, in order to be upgraded. + if (preburn_exists && !preburn_queue_exists) { + let Preburn { to_burn } = move_from>(sender); + publish_preburn_queue(account); + // If the DD has an old preburn balance, this is converted over + // into the new preburn queue when it's upgraded. + if (to_burn.value > 0) { + add_preburn_to_queue(account, PreburnWithMetadata { + preburn: Preburn { to_burn }, + metadata: x"", + }) + } else { + destroy_zero(to_burn) + }; + } + } + spec upgrade_preburn { + let account_addr = signer::address_of(account); + modifies global>(account_addr); + modifies global>(account_addr); + include UpgradePreburnAbortsIf; + include UpgradePreburnEnsures; + } + spec schema UpgradePreburnAbortsIf { + account: signer; + let account_addr = signer::address_of(account); + let upgrade = exists>(account_addr) && !exists>(account_addr); + /// Must abort if the account doesn't have the `PreburnQueue` or + /// `Preburn` resource to satisfy [[H4]][PERMISSION] of `preburn_to`. + include upgrade ==> PublishPreburnQueueAbortsIf; + include Roles::AbortsIfNotDesignatedDealer; + } + spec schema UpgradePreburnEnsures { + account: signer; + let account_addr = signer::address_of(account); + let upgrade = exists>(account_addr) && !exists>(account_addr); + let preburn = global>(account_addr); + ensures upgrade ==> + !exists>(account_addr) && exists>(account_addr); + ensures upgrade && preburn.to_burn.value > 0 ==> + global>(account_addr).preburns == + vec(PreburnWithMetadata { preburn, metadata: x"" }); + ensures upgrade && preburn.to_burn.value == 0 ==> + global>(account_addr).preburns == vec(); + } + + /// Add the `preburn` request to the preburn queue of `account`, and check that the + /// number of preburn requests does not exceed `MAX_OUTSTANDING_PREBURNS`. + fun add_preburn_to_queue(account: &signer, preburn: PreburnWithMetadata) + acquires PreburnQueue { + let account_addr = signer::address_of(account); + assert!(exists>(account_addr), errors::invalid_state(EPREBURN_QUEUE)); + assert!(value(&preburn.preburn.to_burn) > 0, errors::invalid_argument(EPREBURN)); + let preburns = &mut borrow_global_mut>(account_addr).preburns; + assert!( + vector::length(preburns) < MAX_OUTSTANDING_PREBURNS, + errors::limit_exceeded(EPREBURN_QUEUE) + ); + vector::push_back(preburns, preburn); + } + spec add_preburn_to_queue { + pragma opaque; + let account_addr = signer::address_of(account); + let preburns = global>(account_addr).preburns; + let post post_preburns = global>(account_addr).preburns; + modifies global>(account_addr); + aborts_if !exists>(account_addr) with errors::INVALID_STATE; + include AddPreburnToQueueAbortsIf; + ensures exists>(account_addr); + ensures vector::eq_push_back(post_preburns, preburns, preburn); + } + spec schema AddPreburnToQueueAbortsIf { + account: signer; + preburn: PreburnWithMetadata; + let account_addr = signer::address_of(account); + aborts_if preburn.preburn.to_burn.value == 0 with errors::INVALID_ARGUMENT; + aborts_if exists>(account_addr) && + vector::length(global>(account_addr).preburns) >= MAX_OUTSTANDING_PREBURNS + with errors::LIMIT_EXCEEDED; + } + + /// Sends `coin` to the preburn queue for `account`, where it will wait to either be burned + /// or returned to the balance of `account`. + /// Calls to this function will fail if: + /// * `account` does not have a `PreburnQueue` resource published under it; or + /// * the preburn queue is already at capacity (i.e., at `MAX_OUTSTANDING_PREBURNS`); or + /// * `coin` has a `value` field of zero. + public fun preburn_to( + account: &signer, + coin: Diem + ) acquires CurrencyInfo, Preburn, PreburnQueue { + Roles::assert_designated_dealer(account); + // any coin that is preburned needs to have a nonzero value + assert!(value(&coin) > 0, errors::invalid_argument(ECOIN)); + let sender = signer::address_of(account); + // After an upgrade a `Preburn` resource no longer exists in this + // currency, and it is replaced with a `PreburnQueue` resource + // for the same currency. + upgrade_preburn(account); + + let preburn = PreburnWithMetadata { + preburn: Preburn { to_burn: zero() }, + metadata: x"", + }; + preburn_with_resource(coin, &mut preburn.preburn, sender); + add_preburn_to_queue(account, preburn); + } + spec preburn_to { + pragma opaque; + pragma disable_invariants_in_body; + include PreburnToAbortsIf{amount: coin.value}; + include PreburnToEnsures{amount: coin.value}; + let account_addr = signer::address_of(account); + include PreburnWithResourceEmits{amount: coin.value, preburn_address: account_addr}; + } + spec schema PreburnToAbortsIf { + account: signer; + amount: u64; + let account_addr = signer::address_of(account); + /// Must abort if the account doesn't have the PreburnQueue or Preburn resource, or has not + /// the correct role [[H4]][PERMISSION]. + aborts_if !(exists>(account_addr) || exists>(account_addr)); + include Roles::AbortsIfNotDesignatedDealer; + include PreburnAbortsIf; + include UpgradePreburnAbortsIf; + include AddPreburnToQueueAbortsIf{preburn: PreburnWithMetadata{ preburn: spec_make_preburn(amount), metadata: x"" } }; + } + spec schema PreburnToEnsures { + account: signer; + amount: u64; + let account_addr_for_preburn = signer::address_of(account); + /// Removes the preburn resource if it exists + modifies global>(account_addr_for_preburn); + /// Publishes if it doesn't exists. Updates its state either way. + modifies global>(account_addr_for_preburn); + ensures exists>(account_addr_for_preburn); + // The preburn amount in the currency info can be updated. + modifies global>(@CurrencyInfo); + include PreburnEnsures{preburn: spec_make_preburn(amount)}; + } + + /// Remove the oldest preburn request in the `PreburnQueue` + /// resource published under `preburn_address` whose value is equal to `amount`. + /// Calls to this function will fail if: + /// * `preburn_address` doesn't have a `PreburnQueue` resource published under it; or + /// * a preburn request with the correct value for `amount` cannot be found in the preburn queue for `preburn_address`; + fun remove_preburn_from_queue(preburn_address: address, amount: u64): PreburnWithMetadata + acquires PreburnQueue { + assert!(exists>(preburn_address), errors::not_published(EPREBURN_QUEUE)); + // We search from the head of the queue + let index = 0; + let preburn_queue = &mut borrow_global_mut>(preburn_address).preburns; + let queue_length = vector::length(preburn_queue); + + while ({ + spec { + invariant index <= queue_length; + invariant forall j in 0..index: preburn_queue[j].preburn.to_burn.value != amount; + }; + (index < queue_length) + }) { + let elem = vector::borrow(preburn_queue, index); + if (value(&elem.preburn.to_burn) == amount) { + let preburn = vector::remove(preburn_queue, index); + // Make sure that the value is correct + return preburn + }; + index = index + 1; + }; + + spec { + assert index == queue_length; + assert forall j in 0..queue_length: preburn_queue[j].preburn.to_burn.value != amount; + }; + + // If we didn't return already, we couldn't find a preburn with a matching value. + abort errors::invalid_state(EPREBURN_NOT_FOUND) + } + spec remove_preburn_from_queue { + pragma opaque; + modifies global>(preburn_address); + include RemovePreburnFromQueueAbortsIf; + include RemovePreburnFromQueueEnsures; + ensures result.preburn.to_burn.value == amount; + } + spec schema RemovePreburnFromQueueAbortsIf { + preburn_address: address; + amount: u64; + let preburn_queue = global>(preburn_address).preburns; + aborts_if !exists>(preburn_address) with errors::NOT_PUBLISHED; + aborts_if forall i in 0..len(preburn_queue): preburn_queue[i].preburn.to_burn.value != amount with errors::INVALID_STATE; + } + /// > TODO: See this cannot currently be expressed in the MSL. + /// > See https://github.com/diem/diem/issues/7615 for more information. + spec schema RemovePreburnFromQueueEnsures { + preburn_address: address; + amount: u64; + ensures old(exists>(preburn_address)) ==> exists>(preburn_address); + // let preburn_queue = global>(preburn_address).preburns; + // let preburn = Preburn { to_burn: Diem { value: amount }}; + // let (found, index) = vector::index_of(preburn_queue, preburn); + // ensures found ==> vector::eq_remove_elem_at_index(index, preburn_queue, old(preburn_queue)); + } + + /// Permanently removes the coins in the oldest preburn request in the + /// `PreburnQueue` resource under `preburn_address` that has a `to_burn` + /// value of `amount` and updates the market cap accordingly. + /// This function can only be called by the holder of a `BurnCapability`. + /// Calls to this function will fail if the there is no `PreburnQueue` + /// resource under `preburn_address`, or, if there is no preburn request in + /// the preburn queue with a `to_burn` amount equal to `amount`. + public(friend) fun burn_with_capability( + preburn_address: address, + capability: &BurnCapability, + amount: u64, + ) acquires CurrencyInfo, PreburnQueue { + + // Remove the preburn request + let PreburnWithMetadata{ preburn, metadata: _ } = remove_preburn_from_queue(preburn_address, amount); + + // Burn the contained coins + burn_with_resource_cap(&mut preburn, preburn_address, capability); + + let Preburn { to_burn } = preburn; + destroy_zero(to_burn); + } + spec burn_with_capability { + pragma delegate_invariants_to_caller; + include BurnWithResourceCapEmits{preburn: spec_make_preburn(amount)}; + include BurnWithCapabilityAbortsIf; + include BurnWithCapabilityEnsures; + } + spec schema BurnWithCapabilityAbortsIf { + preburn_address: address; + amount: u64; + let preburn = spec_make_preburn(amount); + include AbortsIfNoPreburnQueue; + include RemovePreburnFromQueueAbortsIf; + include BurnWithResourceCapAbortsIf{preburn: preburn}; + } + spec schema BurnWithCapabilityEnsures { + preburn_address: address; + amount: u64; + let preburn = spec_make_preburn(amount); + include BurnWithResourceCapEnsures{preburn: preburn}; + include RemovePreburnFromQueueEnsures; + } + + /// Permanently removes the coins held in the `Preburn` resource (in `to_burn` field) + /// that was stored in a `PreburnQueue` at `preburn_address` and updates the market cap accordingly. + /// This function can only be called by the holder of a `BurnCapability`. + /// Calls to this function will fail if the preburn `to_burn` area for `CoinType` is empty. + fun burn_with_resource_cap( + preburn: &mut Preburn, + preburn_address: address, + _capability: &BurnCapability + ) acquires CurrencyInfo { + let currency_code = currency_code(); + // Abort if no coin present in preburn area + assert!(preburn.to_burn.value > 0, errors::invalid_state(EPREBURN_EMPTY)); + // destroy the coin in Preburn area + let Diem { value } = withdraw_all(&mut preburn.to_burn); + // update the market cap + assert_is_currency(); + let info = borrow_global_mut>(@CurrencyInfo); + assert!(info.total_value >= (value as u128), errors::limit_exceeded(ECURRENCY_INFO)); + info.total_value = info.total_value - (value as u128); + assert!(info.preburn_value >= value, errors::limit_exceeded(EPREBURN)); + info.preburn_value = info.preburn_value - value; + // don't emit burn events for synthetic currenices as this does not + // change the total value of fiat currencies held on-chain. + if (!info.is_synthetic) { + event::emit_event( + &mut info.burn_events, + BurnEvent { + amount: value, + currency_code, + preburn_address, + } + ); + }; + } + spec burn_with_resource_cap { + pragma delegate_invariants_to_caller; + let pre_preburn = preburn; + include BurnWithResourceCapAbortsIf{preburn: pre_preburn}; + include BurnWithResourceCapEnsures{preburn: pre_preburn}; + include BurnWithResourceCapEmits{preburn: pre_preburn}; + } + spec schema BurnWithResourceCapAbortsIf { + preburn: Preburn; + include AbortsIfNoCurrency; + let to_burn = preburn.to_burn.value; + let info = spec_currency_info(); + aborts_if to_burn == 0 with errors::INVALID_STATE; + aborts_if info.total_value < to_burn with errors::LIMIT_EXCEEDED; + aborts_if info.preburn_value < to_burn with errors::LIMIT_EXCEEDED; + } + spec schema BurnWithResourceCapEnsures { + preburn: Preburn; + ensures spec_currency_info().total_value + == old(spec_currency_info().total_value) - preburn.to_burn.value; + ensures spec_currency_info().preburn_value + == old(spec_currency_info().preburn_value) - preburn.to_burn.value; + } + spec schema BurnWithResourceCapEmits { + preburn: Preburn; + preburn_address: address; + let info = spec_currency_info(); + let currency_code = spec_currency_code(); + let handle = info.burn_events; + emits BurnEvent { + amount: preburn.to_burn.value, + currency_code, + preburn_address, + } + to handle if !info.is_synthetic; + } + + /// Cancels the oldest preburn request held in the `PreburnQueue` resource under + /// `preburn_address` with a `to_burn` amount matching `amount`. It then returns these coins to the caller. + /// This function can only be called by the holder of a + /// `BurnCapability`, and will fail if the `PreburnQueue` resource + /// at `preburn_address` does not contain a preburn request of the right amount. + fun cancel_burn_with_capability( + preburn_address: address, + _capability: &BurnCapability, + amount: u64, + ): Diem acquires CurrencyInfo, PreburnQueue { + + // destroy the coin in the preburn area + let PreburnWithMetadata{ preburn: Preburn { to_burn }, metadata: _ } = remove_preburn_from_queue(preburn_address, amount); + + // update the market cap + let currency_code = currency_code(); + let info = borrow_global_mut>(@CurrencyInfo); + assert!(info.preburn_value >= amount, errors::limit_exceeded(EPREBURN)); + info.preburn_value = info.preburn_value - amount; + // Don't emit cancel burn events for synthetic currencies. cancel_burn + // shouldn't be be used for synthetic coins in the first place. + if (!info.is_synthetic) { + event::emit_event( + &mut info.cancel_burn_events, + CancelBurnEvent { + amount, + currency_code, + preburn_address, + } + ); + }; + + to_burn + } + spec cancel_burn_with_capability { + pragma delegate_invariants_to_caller; + modifies global>(preburn_address); + modifies global>(@CurrencyInfo); + include CancelBurnWithCapAbortsIf; + include CancelBurnWithCapEnsures; + include CancelBurnWithCapEmits; + ensures exists>(@CurrencyInfo); + ensures result.value == amount; + ensures result.value > 0; + } + spec schema CancelBurnWithCapAbortsIf { + preburn_address: address; + amount: u64; + let info = global>(@CurrencyInfo); + include AbortsIfNoCurrency; + include RemovePreburnFromQueueAbortsIf; + aborts_if info.preburn_value < amount with errors::LIMIT_EXCEEDED; + } + spec schema CancelBurnWithCapEnsures { + preburn_address: address; + amount: u64; + include RemovePreburnFromQueueEnsures; + let info = global>(@CurrencyInfo); + let post post_info = global>(@CurrencyInfo); + ensures post_info == update_field(info, preburn_value, info.preburn_value - amount); + } + spec schema CancelBurnWithCapEmits { + preburn_address: address; + amount: u64; + let info = spec_currency_info(); + let currency_code = spec_currency_code(); + let handle = info.cancel_burn_events; + emits CancelBurnEvent { + amount, + currency_code, + preburn_address, + } + to handle if !info.is_synthetic; + } + + /// A shortcut for immediately burning a coin. This calls preburn followed by a subsequent burn, and is + /// used for administrative burns, like unpacking an XDX coin or charging fees. + public(friend) fun burn_now( + coin: Diem, + preburn: &mut Preburn, + preburn_address: address, + capability: &BurnCapability + ) acquires CurrencyInfo { + assert!(coin.value > 0, errors::invalid_argument(ECOIN)); + preburn_with_resource(coin, preburn, preburn_address); + burn_with_resource_cap(preburn, preburn_address, capability); + } + spec burn_now { + pragma delegate_invariants_to_caller; + include BurnNowAbortsIf; + let info = spec_currency_info(); + let post post_info = spec_currency_info(); + include PreburnWithResourceEmits{amount: coin.value, preburn_address: preburn_address}; + include BurnWithResourceCapEmits{preburn: Preburn{to_burn: coin}}; + ensures preburn.to_burn.value == 0; + ensures post_info == update_field(info, total_value, info.total_value - coin.value); + } + spec schema BurnNowAbortsIf { + coin: Diem; + preburn: Preburn; + aborts_if coin.value == 0 with errors::INVALID_ARGUMENT; + include PreburnWithResourceAbortsIf{amount: coin.value}; + // The aborts condition for the burn is simplified because of previous call to preburn. + let info = spec_currency_info(); + aborts_if info.total_value < coin.value with errors::LIMIT_EXCEEDED; + } + + /// Removes and returns the `BurnCapability` from `account`. + /// Calls to this function will fail if `account` does not have a + /// published `BurnCapability` resource at the top-level. + public(friend) fun remove_burn_capability(account: &signer): BurnCapability + acquires BurnCapability { + let addr = signer::address_of(account); + assert!(exists>(addr), errors::requires_capability(EBURN_CAPABILITY)); + move_from>(addr) + } + spec remove_burn_capability { + pragma delegate_invariants_to_caller; + include AbortsIfNoBurnCapability; + } + spec schema AbortsIfNoBurnCapability { + account: signer; + aborts_if !exists>(signer::address_of(account)) with errors::REQUIRES_CAPABILITY; + } + + /// Returns the total value of `Diem` that is waiting to be + /// burned throughout the system (i.e. the sum of all outstanding + /// preburn requests across all preburn resources for the `CoinType` + /// currency). + public fun preburn_value(): u64 acquires CurrencyInfo { + assert_is_currency(); + borrow_global>(@CurrencyInfo).preburn_value + } + + /// Create a new `Diem` with a value of `0`. Anyone can call + /// this and it will be successful as long as `CoinType` is a registered currency. + public fun zero(): Diem { + assert_is_currency(); + Diem { value: 0 } + } + + /// Returns the `value` of the passed in `coin`. The value is + /// represented in the base units for the currency represented by + /// `CoinType`. + public fun value(coin: &Diem): u64 { + coin.value + } + + /// Removes `amount` of value from the passed in `coin`. Returns the + /// remaining balance of the passed in `coin`, along with another coin + /// with value equal to `amount`. Calls will fail if `amount > Diem::value(&coin)`. + public fun split(coin: Diem, amount: u64): (Diem, Diem) { + let other = withdraw(&mut coin, amount); + (coin, other) + } + spec split { + aborts_if coin.value < amount with errors::LIMIT_EXCEEDED; + ensures result_1.value == coin.value - amount; + ensures result_2.value == amount; + } + + + /// Withdraw `amount` from the passed-in `coin`, where the original coin is modified in place. + /// After this function is executed, the original `coin` will have + /// `value = original_value - amount`, and the new coin will have a `value = amount`. + /// Calls will abort if the passed-in `amount` is greater than the + /// value of the passed-in `coin`. + public fun withdraw(coin: &mut Diem, amount: u64): Diem { + // Check that `amount` is less than the coin's value + assert!(coin.value >= amount, errors::limit_exceeded(EAMOUNT_EXCEEDS_COIN_VALUE)); + coin.value = coin.value - amount; + Diem { value: amount } + } + spec withdraw { + pragma opaque; + include WithdrawAbortsIf; + ensures coin.value == old(coin.value) - amount; + ensures result.value == amount; + } + spec schema WithdrawAbortsIf { + coin: Diem; + amount: u64; + aborts_if coin.value < amount with errors::LIMIT_EXCEEDED; + } + + /// Return a `Diem` worth `coin.value` and reduces the `value` of the input `coin` to + /// zero. Does not abort. + public fun withdraw_all(coin: &mut Diem): Diem { + let val = coin.value; + withdraw(coin, val) + } + spec withdraw_all { + pragma opaque; + aborts_if false; + ensures result.value == old(coin.value); + ensures coin.value == 0; + } + + /// Takes two coins as input, returns a single coin with the total value of both coins. + /// Destroys on of the input coins. + public fun join(coin1: Diem, coin2: Diem): Diem { + deposit(&mut coin1, coin2); + coin1 + } + spec join { + pragma opaque; + aborts_if coin1.value + coin2.value > max_u64() with errors::LIMIT_EXCEEDED; + ensures result.value == coin1.value + coin2.value; + } + + + /// "Merges" the two coins. + /// The coin passed in by reference will have a value equal to the sum of the two coins + /// The `check` coin is consumed in the process + public fun deposit(coin: &mut Diem, check: Diem) { + let Diem { value } = check; + assert!(MAX_U64 - coin.value >= value, errors::limit_exceeded(ECOIN)); + coin.value = coin.value + value; + } + spec deposit { + pragma opaque; + include DepositAbortsIf; + ensures coin.value == old(coin.value) + check.value; + } + spec schema DepositAbortsIf { + coin: Diem; + check: Diem; + aborts_if coin.value + check.value > MAX_U64 with errors::LIMIT_EXCEEDED; + } + + /// Destroy a zero-value coin. Calls will fail if the `value` in the passed-in `coin` is non-zero + /// so it is impossible to "burn" any non-zero amount of `Diem` without having + /// a `BurnCapability` for the specific `CoinType`. + public fun destroy_zero(coin: Diem) { + let Diem { value } = coin; + assert!(value == 0, errors::invalid_argument(EDESTRUCTION_OF_NONZERO_COIN)) + } + spec destroy_zero { + pragma opaque; + aborts_if coin.value > 0 with errors::INVALID_ARGUMENT; + } + + /////////////////////////////////////////////////////////////////////////// + // Definition of Currencies + /////////////////////////////////////////////////////////////////////////// + + /// Register the type `CoinType` as a currency. Until the type is + /// registered as a currency it cannot be used as a coin/currency unit in Diem. + /// The passed-in `dr_account` must be a specific address (`@CurrencyInfo`) and + /// `dr_account` must also have the correct `DiemRoot` account role. + /// After the first registration of `CoinType` as a + /// currency, additional attempts to register `CoinType` as a currency + /// will abort. + /// When the `CoinType` is registered it publishes the + /// `CurrencyInfo` resource under the `@CurrencyInfo` and + /// adds the currency to the set of `RegisteredCurrencies`. It returns + /// `MintCapability` and `BurnCapability` resources. + public fun register_currency( + dr_account: &signer, + to_xdx_exchange_rate: FixedPoint32, + is_synthetic: bool, + scaling_factor: u64, + fractional_part: u64, + currency_code: vector, + ): (MintCapability, BurnCapability) + { + Roles::assert_diem_root(dr_account); + // Operational constraint that it must be stored under a specific address. + CoreAddresses::assert_currency_info(dr_account); + assert!( + !exists>(signer::address_of(dr_account)), + errors::already_published(ECURRENCY_INFO) + ); + assert!(0 < scaling_factor && scaling_factor <= MAX_SCALING_FACTOR, errors::invalid_argument(ECURRENCY_INFO)); + move_to(dr_account, CurrencyInfo { + total_value: 0, + preburn_value: 0, + to_xdx_exchange_rate, + is_synthetic, + scaling_factor, + fractional_part, + currency_code: copy currency_code, + can_mint: true, + mint_events: event::new_event_handle(dr_account), + burn_events: event::new_event_handle(dr_account), + preburn_events: event::new_event_handle(dr_account), + cancel_burn_events: event::new_event_handle(dr_account), + exchange_rate_update_events: event::new_event_handle(dr_account) + }); + RegisteredCurrencies::add_currency_code( + dr_account, + currency_code, + ); + (MintCapability{}, BurnCapability{}) + } + spec register_currency { + include RegisterCurrencyAbortsIf; + include RegisterCurrencyEnsures; + } + + spec schema RegisterCurrencyAbortsIf { + dr_account: signer; + currency_code: vector; + scaling_factor: u64; + + /// Must abort if the signer does not have the DiemRoot role [[H8]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + aborts_if scaling_factor == 0 || scaling_factor > MAX_SCALING_FACTOR with errors::INVALID_ARGUMENT; + include CoreAddresses::AbortsIfNotCurrencyInfo{account: dr_account}; + aborts_if exists>(signer::address_of(dr_account)) + with errors::ALREADY_PUBLISHED; + include RegisteredCurrencies::AddCurrencyCodeAbortsIf; + } + + spec schema RegisterCurrencyEnsures { + is_synthetic: bool; + to_xdx_exchange_rate: FixedPoint32; + fractional_part: u64; + ensures spec_is_currency(); + ensures is_synthetic_currency() == is_synthetic; + ensures spec_currency_info().total_value == 0; + ensures spec_currency_info().preburn_value == 0; + ensures spec_currency_info().fractional_part == fractional_part; + } + + /// Registers a stable currency (SCS) coin -- i.e., a non-synthetic currency. + /// Resources are published on two distinct + /// accounts: The `CoinInfo` is published on the Diem root account, and the mint and + /// burn capabilities are published on a treasury compliance account. + /// This code allows different currencies to have different treasury compliance + /// accounts. + public fun register_SCS_currency( + dr_account: &signer, + tc_account: &signer, + to_xdx_exchange_rate: FixedPoint32, + scaling_factor: u64, + fractional_part: u64, + currency_code: vector, + ) { + Roles::assert_treasury_compliance(tc_account); + Roles::assert_diem_root(dr_account); + let (mint_cap, burn_cap) = + register_currency( + dr_account, + to_xdx_exchange_rate, + false, // is_synthetic + scaling_factor, + fractional_part, + currency_code, + ); + assert!( + !exists>(signer::address_of(tc_account)), + errors::already_published(EMINT_CAPABILITY) + ); + move_to(tc_account, mint_cap); + publish_burn_capability(tc_account, burn_cap); + } + + spec register_SCS_currency { + include RegisterSCSCurrencyAbortsIf; + include RegisterSCSCurrencyEnsures; + } + spec schema RegisterSCSCurrencyAbortsIf { + tc_account: signer; + dr_account: signer; + currency_code: vector; + scaling_factor: u64; + + /// Must abort if tc_account does not have the TreasuryCompliance role. + /// Only a TreasuryCompliance account can have the MintCapability [[H1]][PERMISSION]. + /// Only a TreasuryCompliance account can have the BurnCapability [[H3]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + + aborts_if exists>(signer::address_of(tc_account)) with errors::ALREADY_PUBLISHED; + include RegisterCurrencyAbortsIf; + include PublishBurnCapAbortsIfs; + } + spec schema RegisterSCSCurrencyEnsures { + tc_account: signer; + to_xdx_exchange_rate: FixedPoint32; + fractional_part: u64; + ensures spec_has_mint_capability(signer::address_of(tc_account)); + ensures spec_xdx_exchange_rate() == to_xdx_exchange_rate; + } + + /// Returns the total amount of currency minted of type `CoinType`. + public fun market_cap(): u128 + acquires CurrencyInfo { + assert_is_currency(); + borrow_global>(@CurrencyInfo).total_value + } + /// Returns the market cap of CoinType. + spec fun spec_market_cap(): u128 { + global>(@CurrencyInfo).total_value + } + + /// Returns the value of the coin in the `FromCoinType` currency in XDX. + /// This should only be used where a _rough_ approximation of the exchange + /// rate is needed. + public fun approx_xdx_for_value(from_value: u64): u64 + acquires CurrencyInfo { + let xdx_exchange_rate = xdx_exchange_rate(); + fixed_point32::multiply_u64(from_value, xdx_exchange_rate) + } + spec approx_xdx_for_value { + pragma opaque; + include ApproxXdmForValueAbortsIf; + ensures result == spec_approx_xdx_for_value(from_value); + } + spec schema ApproxXdmForValueAbortsIf { + from_value: num; + include AbortsIfNoCurrency; + let xdx_exchange_rate = spec_xdx_exchange_rate(); + include fixed_point32::MultiplyAbortsIf{val: from_value, multiplier: xdx_exchange_rate}; + } + + /// Returns the value of the coin in the `FromCoinType` currency in XDX. + /// This should only be used where a rough approximation of the exchange + /// rate is needed. + public fun approx_xdx_for_coin(coin: &Diem): u64 + acquires CurrencyInfo { + let from_value = value(coin); + approx_xdx_for_value(from_value) + } + + /// Returns `true` if the type `CoinType` is a registered currency. + /// Returns `false` otherwise. + public fun is_currency(): bool { + exists>(@CurrencyInfo) + } + + public fun is_SCS_currency(): bool acquires CurrencyInfo { + is_currency() && + !borrow_global>(@CurrencyInfo).is_synthetic + } + + + /// Returns `true` if `CoinType` is a synthetic currency as defined in + /// its `CurrencyInfo`. Returns `false` otherwise. + public fun is_synthetic_currency(): bool + acquires CurrencyInfo { + let addr = @CurrencyInfo; + exists>(addr) && + borrow_global>(addr).is_synthetic + } + + /// Returns the scaling factor for the `CoinType` currency as defined + /// in its `CurrencyInfo`. + public fun scaling_factor(): u64 + acquires CurrencyInfo { + assert_is_currency(); + borrow_global>(@CurrencyInfo).scaling_factor + } + spec fun spec_scaling_factor(): u64 { + global>(@CurrencyInfo).scaling_factor + } + + /// Returns the representable (i.e. real-world) fractional part for the + /// `CoinType` currency as defined in its `CurrencyInfo`. + public fun fractional_part(): u64 + acquires CurrencyInfo { + assert_is_currency(); + borrow_global>(@CurrencyInfo).fractional_part + } + + /// Returns the currency code for the registered currency as defined in + /// its `CurrencyInfo` resource. + public fun currency_code(): vector + acquires CurrencyInfo { + assert_is_currency(); + *&borrow_global>(@CurrencyInfo).currency_code + } + spec currency_code { + pragma opaque; + include AbortsIfNoCurrency; + ensures result == spec_currency_code(); + } + spec fun spec_currency_code(): vector { + spec_currency_info().currency_code + } + + /// Updates the `to_xdx_exchange_rate` held in the `CurrencyInfo` for + /// `FromCoinType` to the new passed-in `xdx_exchange_rate`. + public fun update_xdx_exchange_rate( + tc_account: &signer, + xdx_exchange_rate: FixedPoint32 + ) acquires CurrencyInfo { + Roles::assert_treasury_compliance(tc_account); + assert_is_currency(); + // XDX is not allowed to update the exchange rate. + assert!(currency_code() != b"XDX", errors::invalid_argument(ECOIN)); + let currency_info = borrow_global_mut>(@CurrencyInfo); + currency_info.to_xdx_exchange_rate = xdx_exchange_rate; + event::emit_event( + &mut currency_info.exchange_rate_update_events, + ToXDXExchangeRateUpdateEvent { + currency_code: *¤cy_info.currency_code, + new_to_xdx_exchange_rate: fixed_point32::get_raw_value(*¤cy_info.to_xdx_exchange_rate), + } + ); + } + spec update_xdx_exchange_rate { + include UpdateXDXExchangeRateAbortsIf; + include UpdateXDXExchangeRateEnsures; + include UpdateXDXExchangeRateEmits; + } + + spec schema UpdateXDXExchangeRateAbortsIf { + tc_account: signer; + /// Must abort if the account does not have the TreasuryCompliance Role [[H5]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + + include AbortsIfNoCurrency; + aborts_if spec_currency_code() == b"XDX" with errors::INVALID_ARGUMENT; + } + spec schema UpdateXDXExchangeRateEnsures { + xdx_exchange_rate: FixedPoint32; + ensures spec_currency_info().to_xdx_exchange_rate == xdx_exchange_rate; + } + + spec schema UpdateXDXExchangeRateEmits { + xdx_exchange_rate: FixedPoint32; + let handle = global>(@CurrencyInfo).exchange_rate_update_events; + let msg = ToXDXExchangeRateUpdateEvent { + currency_code: global>(@CurrencyInfo).currency_code, + new_to_xdx_exchange_rate: fixed_point32::get_raw_value(xdx_exchange_rate) + }; + emits msg to handle; + } + + /// Returns the (rough) exchange rate between `CoinType` and `XDX` + public fun xdx_exchange_rate(): FixedPoint32 + acquires CurrencyInfo { + assert_is_currency(); + *&borrow_global>(@CurrencyInfo).to_xdx_exchange_rate + } + spec xdx_exchange_rate { + pragma opaque; + include AbortsIfNoCurrency; + let info = global>(@CurrencyInfo); + ensures result == info.to_xdx_exchange_rate; + } + + /// There may be situations in which we disallow the further minting of + /// coins in the system without removing the currency. This function + /// allows the association treasury compliance account to control whether or not further coins of + /// `CoinType` can be minted or not. If this is called with `can_mint = true`, + /// then minting is allowed, if `can_mint = false` then minting is + /// disallowed until it is turned back on via this function. All coins + /// start out in the default state of `can_mint = true`. + public fun update_minting_ability( + tc_account: &signer, + can_mint: bool, + ) + acquires CurrencyInfo { + Roles::assert_treasury_compliance(tc_account); + assert_is_currency(); + let currency_info = borrow_global_mut>(@CurrencyInfo); + currency_info.can_mint = can_mint; + } + spec update_minting_ability { + include UpdateMintingAbilityAbortsIf; + include UpdateMintingAbilityEnsures; + } + spec schema UpdateMintingAbilityAbortsIf { + tc_account: signer; + include AbortsIfNoCurrency; + /// Only the TreasuryCompliance role can enable/disable minting [[H2]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + } + spec schema UpdateMintingAbilityEnsures { + tc_account: signer; + can_mint: bool; + ensures spec_currency_info().can_mint == can_mint; + } + + /////////////////////////////////////////////////////////////////////////// + // Helper functions + /////////////////////////////////////////////////////////////////////////// + + /// Asserts that `CoinType` is a registered currency. + public fun assert_is_currency() { + assert!(is_currency(), errors::not_published(ECURRENCY_INFO)); + } + spec assert_is_currency { + pragma opaque; + include AbortsIfNoCurrency; + } + spec schema AbortsIfNoCurrency { + aborts_if !spec_is_currency() with errors::NOT_PUBLISHED; + } + + public fun assert_is_SCS_currency() acquires CurrencyInfo { + assert_is_currency(); + assert!(is_SCS_currency(), errors::invalid_state(ECURRENCY_INFO)); + } + spec schema AbortsIfNoSCSCurrency { + include AbortsIfNoCurrency; + aborts_if !is_SCS_currency() with errors::INVALID_STATE; + } + + // ================================================================= + // Module Specification + + spec module {} // switch documentation context back to module level + + /// # Access Control + // TODO: The XUS module now has the access control spec for XUS. The access + // control spec in this module can be removed when no longer necessary. + + spec module { + /// Only mint functions can increase the total amount of currency [[H1]][PERMISSION]. + apply TotalValueNotIncrease to * + except mint, mint_with_capability; + + /// In order to successfully call `mint` and `mint_with_capability`, MintCapability is + /// required. MintCapability must be only granted to a TreasuryCompliance account [[H1]][PERMISSION]. + /// Only `register_SCS_currency` creates MintCapability, which must abort if the account + /// does not have the TreasuryCompliance role [[H1]][PERMISSION]. + apply PreserveMintCapAbsence to * except register_SCS_currency; + apply Roles::AbortsIfNotTreasuryCompliance{account: tc_account} to register_SCS_currency; + + /// Only TreasuryCompliance can have MintCapability [[H1]][PERMISSION]. + /// If an account has MintCapability, it is a TreasuryCompliance account. + invariant + forall mint_cap_owner: address where exists>(mint_cap_owner): + Roles::spec_has_treasury_compliance_role_addr(mint_cap_owner); + + /// MintCapability is not transferrable [[J1]][PERMISSION]. + apply PreserveMintCapExistence to *; + + /// The permission "MintCurrency" is unique per currency [[I1]][PERMISSION]. + /// At most one address has a mint capability for SCS CoinType + invariant is_SCS_currency() ==> ( + forall mint_cap_owner1: address, mint_cap_owner2: address + where ( + exists>(mint_cap_owner1) && + exists>(mint_cap_owner2) + ): mint_cap_owner1 == mint_cap_owner2 + ); + + /// If an address has a mint capability, it is an SCS currency. + invariant + forall addr3: address where spec_has_mint_capability(addr3): + is_SCS_currency(); + } + + /// ## Minting + // > TODO These can be simplified using global invariants + + spec schema TotalValueNotIncrease { + /// The total amount of currency does not increase. + ensures old(spec_is_currency()) + ==> spec_currency_info().total_value <= old(spec_currency_info().total_value); + } + spec schema PreserveMintCapExistence { + /// The existence of MintCapability is preserved. + ensures forall addr: address: + old(exists>(addr)) ==> + exists>(addr); + } + spec schema PreserveMintCapAbsence { + /// The absence of MintCapability is preserved. + ensures forall addr: address: + old(!exists>(addr)) ==> + !exists>(addr); + } + + /// ## Burning + + spec schema TotalValueNotDecrease { + /// The total amount of currency does not decrease. + ensures old(spec_is_currency()) + ==> spec_currency_info().total_value >= old(spec_currency_info().total_value); + } + spec schema PreserveBurnCapExistence { + /// The existence of BurnCapability is preserved. + ensures forall addr: address: + old(exists>(addr)) ==> + exists>(addr); + } + spec schema PreserveBurnCapAbsence { + /// The absence of BurnCapability is preserved. + ensures forall addr: address: + old(!exists>(addr)) ==> + !exists>(addr); + } + spec module { + /// Only burn functions can decrease the total amount of currency [[H3]][PERMISSION]. + apply TotalValueNotDecrease to * + except burn, burn_with_capability, burn_with_resource_cap, + burn_now; + + /// In order to successfully call the burn functions, BurnCapability is required. + /// BurnCapability must be only granted to a TreasuryCompliance account [[H3]][PERMISSION]. + /// Only `register_SCS_currency` and `publish_burn_capability` publish BurnCapability, + /// which must abort if the account does not have the TreasuryCompliance role [[H8]][PERMISSION]. + apply PreserveBurnCapAbsence to * + except register_SCS_currency, publish_burn_capability; + apply Roles::AbortsIfNotTreasuryCompliance{account: tc_account} to register_SCS_currency; + + /// Only TreasuryCompliance can have BurnCapability [[H3]][PERMISSION]. + /// If an account has BurnCapability, it is a TreasuryCompliance account. + invariant + forall addr1: address: + exists>(addr1) ==> + Roles::spec_has_treasury_compliance_role_addr(addr1); + + /// BurnCapability is not transferrable [[J3]][PERMISSION]. BurnCapability can be extracted from an + /// account, but is always moved back to the original account. This is the case in + /// `TransactionFee::burn_fees` which is the only user of `remove_burn_capability` and + /// `publish_burn_capability`. + apply PreserveBurnCapExistence to * except remove_burn_capability; + + // The permission "BurnCurrency" is unique per currency [[I3]][PERMISSION]. At most one BurnCapability + // can exist for each SCS CoinType. It is because when a new CoinType is registered in + // `register_currency`, BurnCapability is packed (i.e., its instance is created) + // only one time. + } + + + /// ## Preburning + + spec schema PreburnValueNotIncrease { + /// The preburn value of currency does not increase. + ensures old(spec_is_currency()) + ==> spec_currency_info().preburn_value <= old(spec_currency_info().preburn_value); + } + spec schema PreburnValueNotDecrease { + /// The the preburn value of currency does not decrease. + ensures old(spec_is_currency()) + ==> spec_currency_info().preburn_value >= old(spec_currency_info().preburn_value); + } + spec schema PreservePreburnQueueExistence { + /// The existence of the `PreburnQueue` resource is preserved. + ensures forall addr: address: + old(exists>(addr)) ==> + exists>(addr); + } + spec schema PreservePreburnQueueAbsence { + /// The absence of a `PreburnQueue` is preserved. + /// > NB: As part of the upgrade process, we also tie this in with the + /// non-existence of a `Preburn` resource as well. Once the upgrade + /// process is complete this additional existence check can be removed. + ensures forall addr: address: + old(!(exists>(addr) || exists>(addr))) ==> + !exists>(addr); + } + + spec module { + /// Only burn functions can decrease the preburn value of currency [[H4]][PERMISSION]. + apply PreburnValueNotDecrease to * + except burn, burn_with_capability, burn_with_resource_cap, + burn_now, cancel_burn, cancel_burn_with_capability; + + /// Only preburn functions can increase the preburn value of currency [[H4]][PERMISSION]. + apply PreburnValueNotIncrease to * + except preburn_to, preburn_with_resource; + + /// In order to successfully call the preburn functions, Preburn is required. Preburn must + /// be only granted to a DesignatedDealer account [[H4]][PERMISSION]. Only `publish_preburn_queue_to_account` and `publish_preburn_queue` + /// publishes `PreburnQueue`, which must abort if the account does not have the DesignatedDealer role [[H4]][PERMISSION]. + apply Roles::AbortsIfNotDesignatedDealer to publish_preburn_queue, publish_preburn_queue_to_account; + apply PreservePreburnQueueAbsence to * except + publish_preburn_queue, + publish_preburn_queue_to_account; + + /// Only DesignatedDealer can have PreburnQueue [[H3]][PERMISSION]. + /// If an account has PreburnQueue, it is a DesignatedDealer account. + /// > NB: during the transition this holds for both `Preburn` and `PreburnQueue` resources. + invariant + forall addr1: address: + exists>(addr1) || exists>(addr1) ==> + Roles::spec_has_designated_dealer_role_addr(addr1); + + /// If there is a preburn resource published, it must have a value of zero. + /// If there is a preburn resource published, there cannot also be a + /// `PreburnQueue` resource published under that same account for the + /// same currency. + /// > NB: This invariant is part of the upgrade process, eventually + /// this will be removed once all DD's have been upgraded to + /// using the `PreburnQueue`. + invariant forall dd_addr: address + where exists>(dd_addr): + global>(dd_addr).to_burn.value == 0 && + !exists>(dd_addr); + + /// If there is a `PreburnQueue` resource published, then there cannot + /// also be a `Preburn` resource for that same currency published under + /// the same address. + invariant forall dd_addr: address + where exists>(dd_addr): + !exists>(dd_addr); + + /// A `Preburn` resource can only be published holding a currency type. + invariant forall addr: address + where exists>(addr): + spec_is_currency(); + + /// A `PreburnQueue` resource can only be published holding a currency type. + /// >TODO: This assertion is causing a violation for unknown reasons, probably + /// a prover bug. + // invariant forall addr: address + // where exists>(addr): + // spec_is_currency(); + + /// Preburn is not transferrable [[J4]][PERMISSION]. + apply PreservePreburnQueueExistence to *; + + /// resource struct `CurrencyInfo` is persistent + invariant update forall dr_addr: address + where old(exists>(dr_addr)): + exists>(dr_addr); + + /// resource struct `PreburnQueue` is persistent + invariant update forall tc_addr: address + where old(exists>(tc_addr)): + exists>(tc_addr); + + /// resource struct `MintCapability` is persistent + invariant update forall tc_addr: address + where old(exists>(tc_addr)): + exists>(tc_addr); + } + + + /// ## Update Exchange Rates + spec module { + /// Only TreasuryCompliance can change the exchange rate [[H5]][PERMISSION]. + invariant update old(spec_is_currency()) ==> + ((spec_xdx_exchange_rate() != old(spec_xdx_exchange_rate())) + ==> Roles::spec_signed_by_treasury_compliance_role()); + } + + /// ## Enable/disable minting + spec module { + /// Only TreasuryCompliance can enable/disable minting [[H2]][PERMISSION]. + invariant update old(spec_is_currency()) ==> + ((spec_can_mint() != old(spec_can_mint())) + ==> Roles::spec_signed_by_treasury_compliance_role()); + } + + /// ## Register new currency + spec module { + /// Only DiemRoot can register a new currency [[H8]][PERMISSION]. + invariant update + !old(spec_is_currency()) && spec_is_currency() + ==> Roles::spec_signed_by_diem_root_role(); + } + + + /// # Lemmas + + spec module { + // These lemmas are needed to prove the uniqueness of MintCapability/BurnCapability. + + /// If an address has a mint capability, it is a registered currency. + invariant + forall a: address where spec_has_mint_capability(a): + is_currency(); + + /// If an address has a burn capability, it is a registered currency. + invariant + forall a: address where spec_has_burn_capability(a): + is_currency(); + } + + /// # Helper Functions + + spec module { + /// Checks whether currency is registered. Mirrors `Self::is_currency`. + fun spec_is_currency(): bool { + exists>(@CurrencyInfo) + } + + /// Returns currency information. + fun spec_currency_info(): CurrencyInfo { + global>(@CurrencyInfo) + } + + /// Specification version of `Self::approx_xdx_for_value`. + fun spec_approx_xdx_for_value(value: num): num { + fixed_point32::spec_multiply_u64(value, spec_xdx_exchange_rate()) + } + + /// Returns the `to_xdx_exchange_rate` of CoinType + fun spec_xdx_exchange_rate(): FixedPoint32 { + global>(@CurrencyInfo).to_xdx_exchange_rate + } + + /// Returns the `to_xdx_exchange_rate` of CoinType + fun spec_can_mint(): bool { + global>(@CurrencyInfo).can_mint + } + + /// Checks whether the currency has a mint capability. + /// This is only relevant for SCS coins. + fun spec_has_mint_capability(addr: address): bool { + exists>(addr) + } + + /// Returns true if a BurnCapability for CoinType exists at addr. + /// This is only relevant for SCS coins. + fun spec_has_burn_capability(addr: address): bool { + exists>(addr) + } + + /// Returns true if a PrebunQueue for CoinType exists at addr. + fun spec_has_preburn_queue(addr: address): bool { + exists>(addr) + } + + /// Returns true if a Prebun for CoinType exists at addr. + fun spec_has_preburn(addr: address): bool { + exists>(addr) + } + + /// Returns the Preburn in the preburn queue. + fun spec_make_preburn(amount: u64): Preburn { + Preburn { to_burn: Diem { value: amount }} + } + + fun spec_signed_by_mint_capability_owner(): bool { + (exists a: address: signer::is_txn_signer_addr(a) + && spec_has_mint_capability(a)) + } + + fun spec_signed_by_burn_capability_owner(): bool { + (exists a: address: signer::is_txn_signer_addr(a) + && spec_has_burn_capability(a)) + } + + fun spec_signed_by_preburn_queue_owner(): bool { + (exists a: address: signer::is_txn_signer_addr(a) + && spec_has_preburn_queue(a)) + } + + fun spec_signed_by_preburn_owner(): bool { + (exists a: address: signer::is_txn_signer_addr(a) + && spec_has_preburn(a)) + } + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemAccount.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemAccount.move new file mode 100644 index 000000000..4e01fc090 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemAccount.move @@ -0,0 +1,2617 @@ +/// The `DiemAccount` module manages accounts. It defines the `DiemAccount` resource and +/// numerous auxiliary data structures. It also defines the prolog and epilog that run +/// before and after every transaction. + +module DiemFramework::DiemAccount { + use DiemFramework::AccountFreezing; + use DiemFramework::CoreAddresses; + use DiemFramework::ChainId; + use DiemFramework::AccountLimits::{Self, AccountLimitMutationCapability}; + use DiemFramework::XUS::XUS; + use DiemFramework::DualAttestation; + use DiemFramework::XDX::XDX; + use DiemFramework::DiemConfig; + use DiemFramework::DiemTimestamp; + use DiemFramework::DiemTransactionPublishingOption; + use DiemFramework::SlidingNonce; + use DiemFramework::TransactionFee; + use DiemFramework::ValidatorConfig; + use DiemFramework::ValidatorOperatorConfig; + use DiemFramework::VASP; + use DiemFramework::DesignatedDealer; + use DiemFramework::Diem::{Self, Diem}; + use DiemFramework::Roles; + use DiemFramework::VASPDomain; + use DiemFramework::CRSN; + use std::bcs; + use std::event::{Self, EventHandle}; + use std::errors; + use std::hash; + use std::option::{Self, Option}; + use std::signer; + use std::vector; + + friend DiemFramework::AccountAdministrationScripts; + + /// An `address` is a Diem Account iff it has a published DiemAccount resource. + struct DiemAccount has key { + /// The current authentication key. + /// This can be different from the key used to create the account + authentication_key: vector, + /// A `withdraw_capability` allows whoever holds this capability + /// to withdraw from the account. At the time of account creation + /// this capability is stored in this option. It can later be removed + /// by `extract_withdraw_capability` and also restored via `restore_withdraw_capability`. + withdraw_capability: Option, + /// A `key_rotation_capability` allows whoever holds this capability + /// the ability to rotate the authentication key for the account. At + /// the time of account creation this capability is stored in this + /// option. It can later be "extracted" from this field via + /// `extract_key_rotation_capability`, and can also be restored via + /// `restore_key_rotation_capability`. + key_rotation_capability: Option, + /// Event handle to which ReceivePaymentEvents are emitted when + /// payments are received. + received_events: EventHandle, + /// Event handle to which SentPaymentEvents are emitted when + /// payments are sent. + sent_events: EventHandle, + /// The current sequence number of the account. + /// Incremented by one each time a transaction is submitted by + /// this account. + sequence_number: u64, + } + + /// A resource that holds the total value of currency of type `Token` + /// currently held by the account. + struct Balance has key { + /// Stores the value of the balance in its balance field. A coin has + /// a `value` field. The amount of money in the balance is changed + /// by modifying this field. + coin: Diem, + } + + /// The holder of WithdrawCapability for account_address can withdraw Diem from + /// account_address/DiemAccount/balance. + /// There is at most one WithdrawCapability in existence for a given address. + struct WithdrawCapability has store { + /// Address that WithdrawCapability was associated with when it was created. + /// This field does not change. + account_address: address, + } + + /// The holder of KeyRotationCapability for account_address can rotate the authentication key for + /// account_address (i.e., write to account_address/DiemAccount/authentication_key). + /// There is at most one KeyRotationCapability in existence for a given address. + struct KeyRotationCapability has store { + /// Address that KeyRotationCapability was associated with when it was created. + /// This field does not change. + account_address: address, + } + + /// A wrapper around an `AccountLimitMutationCapability` which is used to check for account limits + /// and to record freeze/unfreeze events. + struct AccountOperationsCapability has key { + limits_cap: AccountLimitMutationCapability, + creation_events: event::EventHandle, + } + + /// A resource that holds the event handle for all the past WriteSet transactions that have been committed on chain. + struct DiemWriteSetManager has key { + upgrade_events: event::EventHandle, + } + + + /// Message for sent events + struct SentPaymentEvent has drop, store { + /// The amount of Diem sent + amount: u64, + /// The code symbol for the currency that was sent + currency_code: vector, + /// The address that was paid + payee: address, + /// Metadata associated with the payment + metadata: vector, + } + + /// Message for received events + struct ReceivedPaymentEvent has drop, store { + /// The amount of Diem received + amount: u64, + /// The code symbol for the currency that was received + currency_code: vector, + /// The address that sent the coin + payer: address, + /// Metadata associated with the payment + metadata: vector, + } + + /// Message for committed WriteSet transaction. + struct AdminTransactionEvent has drop, store { + // The block time when this WriteSet is committed. + committed_timestamp_secs: u64, + } + + /// Message for creation of a new account + struct CreateAccountEvent has drop, store { + /// Address of the created account + created: address, + /// Role of the created account + role_id: u64 + } + + const MAX_U64: u128 = 18446744073709551615; + + /// The `DiemAccount` resource is not in the required state + const EACCOUNT: u64 = 0; + /// Tried to deposit a coin whose value was zero + const ECOIN_DEPOSIT_IS_ZERO: u64 = 2; + /// Tried to deposit funds that would have surpassed the account's limits + const EDEPOSIT_EXCEEDS_LIMITS: u64 = 3; + /// Tried to create a balance for an account whose role does not allow holding balances + const EROLE_CANT_STORE_BALANCE: u64 = 4; + /// The account does not hold a large enough balance in the specified currency + const EINSUFFICIENT_BALANCE: u64 = 5; + /// The withdrawal of funds would have exceeded the the account's limits + const EWITHDRAWAL_EXCEEDS_LIMITS: u64 = 6; + /// The `WithdrawCapability` for this account has already been extracted + const EWITHDRAW_CAPABILITY_ALREADY_EXTRACTED: u64 = 7; + /// The provided authentication had an invalid length + const EMALFORMED_AUTHENTICATION_KEY: u64 = 8; + /// The `KeyRotationCapability` for this account has already been extracted + const EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED: u64 = 9; + /// An account cannot be created at the reserved VM address of 0x0 + const ECANNOT_CREATE_AT_VM_RESERVED: u64 = 10; + /// The `WithdrawCapability` for this account is not extracted + const EWITHDRAW_CAPABILITY_NOT_EXTRACTED: u64 = 11; + /// Tried to add a balance in a currency that this account already has + const EADD_EXISTING_CURRENCY: u64 = 15; + /// Attempted to send funds to an account that does not exist + const EPAYEE_DOES_NOT_EXIST: u64 = 17; + /// Attempted to send funds in a currency that the receiving account does not hold. + /// e.g., `Diem` to an account that exists, but does not have a `Balance` resource + const EPAYEE_CANT_ACCEPT_CURRENCY_TYPE: u64 = 18; + /// Tried to withdraw funds in a currency that the account does hold + const EPAYER_DOESNT_HOLD_CURRENCY: u64 = 19; + /// An invalid amount of gas units was provided for execution of the transaction + const EGAS: u64 = 20; + /// The `AccountOperationsCapability` was not in the required state + const EACCOUNT_OPERATIONS_CAPABILITY: u64 = 22; + /// The `DiemWriteSetManager` was not in the required state + const EWRITESET_MANAGER: u64 = 23; + /// An account cannot be created at the reserved core code address of 0x1 + const ECANNOT_CREATE_AT_CORE_CODE: u64 = 24; + + /// Prologue errors. These are separated out from the other errors in this + /// module since they are mapped separately to major VM statuses, and are + /// important to the semantics of the system. + const PROLOGUE_EACCOUNT_FROZEN: u64 = 1000; + const PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY: u64 = 1001; + const PROLOGUE_ESEQUENCE_NUMBER_TOO_OLD: u64 = 1002; + const PROLOGUE_ESEQUENCE_NUMBER_TOO_NEW: u64 = 1003; + const PROLOGUE_EACCOUNT_DNE: u64 = 1004; + const PROLOGUE_ECANT_PAY_GAS_DEPOSIT: u64 = 1005; + const PROLOGUE_ETRANSACTION_EXPIRED: u64 = 1006; + const PROLOGUE_EBAD_CHAIN_ID: u64 = 1007; + const PROLOGUE_ESCRIPT_NOT_ALLOWED: u64 = 1008; + const PROLOGUE_EMODULE_NOT_ALLOWED: u64 = 1009; + const PROLOGUE_EINVALID_WRITESET_SENDER: u64 = 1010; + const PROLOGUE_ESEQUENCE_NUMBER_TOO_BIG: u64 = 1011; + const PROLOGUE_EBAD_TRANSACTION_FEE_CURRENCY: u64 = 1012; + const PROLOGUE_ESECONDARY_KEYS_ADDRESSES_COUNT_MISMATCH: u64 = 1013; + const PROLOGUE_ESEQ_NONCE_INVALID: u64 = 1014; + + /// Initialize this module. This is only callable from genesis. + public fun initialize( + dr_account: &signer, + dummy_auth_key_prefix: vector, + ) acquires AccountOperationsCapability { + DiemTimestamp::assert_genesis(); + // Operational constraint, not a privilege constraint. + CoreAddresses::assert_diem_root(dr_account); + + create_diem_root_account( + copy dummy_auth_key_prefix, + ); + create_treasury_compliance_account( + dr_account, + copy dummy_auth_key_prefix, + ); + } + + spec initialize { + pragma opaque; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + include CreateDiemRootAccountAbortsIf{auth_key_prefix: dummy_auth_key_prefix}; + include CreateTreasuryComplianceAccountAbortsIf{auth_key_prefix: dummy_auth_key_prefix}; + aborts_if exists(@TreasuryCompliance) + with errors::ALREADY_PUBLISHED; + + // modifies and ensures needed to make this function opaque. + include CreateDiemRootAccountModifies; + include CreateDiemRootAccountEnsures; + include CreateTreasuryComplianceAccountModifies; + include CreateTreasuryComplianceAccountEnsures; + } + + /// Return `true` if `addr` has already published account limits for `Token` + fun has_published_account_limits(addr: address): bool { + if (VASP::is_vasp(addr)) { + VASP::has_account_limits(addr) + } + else { + AccountLimits::has_window_published(addr) + } + } + spec fun spec_has_published_account_limits(addr: address): bool { + if (VASP::is_vasp(addr)) VASP::spec_has_account_limits(addr) + else AccountLimits::has_window_published(addr) + } + + /// Returns whether we should track and record limits for the `payer` or `payee` account. + /// Depending on the `is_withdrawal` flag passed in we determine whether the + /// `payer` or `payee` account is being queried. `VASP->any` and + /// `any->VASP` transfers are tracked in the VASP. + fun should_track_limits_for_account( + payer: address, payee: address, is_withdrawal: bool + ): bool { + if (is_withdrawal) { + has_published_account_limits(payer) && + VASP::is_vasp(payer) && + !VASP::is_same_vasp(payer, payee) + } else { + has_published_account_limits(payee) && + VASP::is_vasp(payee) && + !VASP::is_same_vasp(payee, payer) + } + } + spec should_track_limits_for_account { + pragma opaque; + aborts_if false; + ensures result == spec_should_track_limits_for_account(payer, payee, is_withdrawal); + } + spec fun spec_should_track_limits_for_account( + payer: address, payee: address, is_withdrawal: bool + ): bool { + if (is_withdrawal) { + spec_has_published_account_limits(payer) && + VASP::is_vasp(payer) && + !VASP::spec_is_same_vasp(payer, payee) + } else { + spec_has_published_account_limits(payee) && + VASP::is_vasp(payee) && + !VASP::spec_is_same_vasp(payee, payer) + } + } + + /// Record a payment of `to_deposit` from `payer` to `payee` with the attached `metadata` + fun deposit( + payer: address, + payee: address, + to_deposit: Diem, + metadata: vector, + metadata_signature: vector, + dual_attestation: bool, + ) acquires DiemAccount, Balance, AccountOperationsCapability { + DiemTimestamp::assert_operating(); + AccountFreezing::assert_not_frozen(payee); + + // Check that the `to_deposit` coin is non-zero + let deposit_value = Diem::value(&to_deposit); + assert!(deposit_value > 0, errors::invalid_argument(ECOIN_DEPOSIT_IS_ZERO)); + // Check that an account exists at `payee` + assert!(exists_at(payee), errors::not_published(EPAYEE_DOES_NOT_EXIST)); + // Check that `payee` can accept payments in `Token` + assert!( + exists>(payee), + errors::invalid_argument(EPAYEE_CANT_ACCEPT_CURRENCY_TYPE) + ); + + if (dual_attestation) { + // Check that the payment complies with dual attestation rules + DualAttestation::assert_payment_ok( + payer, payee, deposit_value, copy metadata, metadata_signature + ); + }; + + // Ensure that this deposit is compliant with the account limits on + // this account. + if (should_track_limits_for_account(payer, payee, false)) { + assert!( + AccountLimits::update_deposit_limits( + deposit_value, + VASP::parent_address(payee), + &borrow_global(@DiemRoot).limits_cap + ), + errors::limit_exceeded(EDEPOSIT_EXCEEDS_LIMITS) + ) + }; + + // Deposit the `to_deposit` coin + Diem::deposit(&mut borrow_global_mut>(payee).coin, to_deposit); + + // Log a received event + event::emit_event( + &mut borrow_global_mut(payee).received_events, + ReceivedPaymentEvent { + amount: deposit_value, + currency_code: Diem::currency_code(), + payer, + metadata + } + ); + } + spec deposit { + pragma opaque; + modifies global>(payee); + modifies global(payee); + modifies global>(VASP::spec_parent_address(payee)); + let amount = to_deposit.value; + include DepositAbortsIf{amount: amount}; + include DepositOverflowAbortsIf{amount: amount}; + include DepositEnsures{amount: amount}; + include DepositEmits{amount: amount}; + include dual_attestation ==> DualAttestation::AssertPaymentOkAbortsIf{value: amount}; + } + spec schema DepositAbortsIf { + payer: address; + payee: address; + amount: u64; + metadata: vector; + include DepositAbortsIfRestricted; + include AccountFreezing::AbortsIfFrozen{account: payee}; + aborts_if !exists>(payee) with errors::INVALID_ARGUMENT; + aborts_if !exists_at(payee) with errors::NOT_PUBLISHED; + } + spec schema DepositOverflowAbortsIf { + payee: address; + amount: u64; + aborts_if balance(payee) + amount > max_u64() with errors::LIMIT_EXCEEDED; + } + spec schema DepositAbortsIfRestricted { + payer: address; + payee: address; + amount: u64; + metadata: vector; + include DiemTimestamp::AbortsIfNotOperating; + aborts_if amount == 0 with errors::INVALID_ARGUMENT; + include + spec_should_track_limits_for_account(payer, payee, false) ==> + AccountLimits::UpdateDepositLimitsAbortsIf { + addr: VASP::spec_parent_address(payee), + }; + aborts_if + spec_should_track_limits_for_account(payer, payee, false) && + !AccountLimits::spec_update_deposit_limits(amount, VASP::spec_parent_address(payee)) + with errors::LIMIT_EXCEEDED; + include Diem::AbortsIfNoCurrency; + } + spec schema DepositEnsures { + payee: address; + amount: u64; + + // TODO(wrwg): precisely specify what changed in the modified resources using `update_field` + ensures exists>(payee); + ensures balance(payee) == old(balance(payee)) + amount; + + ensures exists(payee); + ensures global(payee).withdraw_capability + == old(global(payee).withdraw_capability); + ensures global(payee).authentication_key + == old(global(payee).authentication_key); + + ensures event::spec_guid_eq(global(payee).sent_events, + old(global(payee).sent_events)); + ensures event::spec_guid_eq(global(payee).received_events, + old(global(payee).received_events)); + } + spec schema DepositEmits { + payer: address; + payee: address; + amount: u64; + metadata: vector; + let handle = global(payee).received_events; + let msg = ReceivedPaymentEvent { + amount, + currency_code: Diem::spec_currency_code(), + payer, + metadata + }; + emits msg to handle; + } + + /// Mint 'mint_amount' to 'designated_dealer_address' for 'tier_index' tier. + /// Max valid tier index is 3 since there are max 4 tiers per DD. + /// Sender should be treasury compliance account and receiver authorized DD. + public fun tiered_mint( + tc_account: &signer, + designated_dealer_address: address, + mint_amount: u64, + tier_index: u64, + ) acquires DiemAccount, Balance, AccountOperationsCapability { + Roles::assert_treasury_compliance(tc_account); + let coin = DesignatedDealer::tiered_mint( + tc_account, mint_amount, designated_dealer_address, tier_index + ); + // Use the reserved address as the payer because the funds did not come from an existing + // balance + deposit(@VMReserved, designated_dealer_address, coin, x"", x"", false) + } + + spec tiered_mint { + pragma opaque; + modifies global(designated_dealer_address); + modifies global(designated_dealer_address); + modifies global>(designated_dealer_address); + modifies global>(designated_dealer_address); + modifies global>(VASP::spec_parent_address(designated_dealer_address)); + modifies global>(@CurrencyInfo); + include TieredMintAbortsIf; + include TieredMintEnsures; + include TieredMintEmits; + } + spec schema TieredMintAbortsIf { + tc_account: signer; + designated_dealer_address: address; + mint_amount: u64; + tier_index: u64; + include DesignatedDealer::TieredMintAbortsIf{dd_addr: designated_dealer_address, amount: mint_amount}; + include DepositAbortsIf{payer: @VMReserved, + payee: designated_dealer_address, amount: mint_amount, metadata: x""}; + include DepositOverflowAbortsIf{payee: designated_dealer_address, amount: mint_amount}; + } + spec schema TieredMintEnsures { + designated_dealer_address: address; + mint_amount: u64; + let dealer_balance = global>(designated_dealer_address).coin.value; + let post post_dealer_balance = global>(designated_dealer_address).coin.value; + let currency_info = global>(@CurrencyInfo); + let post post_currency_info = global>(@CurrencyInfo); + /// Total value of the currency increases by `amount`. + ensures post_currency_info == update_field(currency_info, total_value, currency_info.total_value + mint_amount); + /// The balance of designated dealer increases by `amount`. + ensures post_dealer_balance == dealer_balance + mint_amount; + } + spec schema TieredMintEmits { + tc_account: signer; + designated_dealer_address: address; + mint_amount: u64; + tier_index: u64; + include DepositEmits{ + payer: @VMReserved, + payee: designated_dealer_address, + amount: mint_amount, + metadata: x"" + }; + include DesignatedDealer::TieredMintEmits{dd_addr: designated_dealer_address, amount: mint_amount}; + } + + // Cancel the burn request from `preburn_address` and return the funds. + // Fails if the sender does not have a published MintCapability. + public fun cancel_burn( + account: &signer, + preburn_address: address, + amount: u64, + ) acquires DiemAccount, Balance, AccountOperationsCapability { + let coin = Diem::cancel_burn(account, preburn_address, amount); + // record both sender and recipient as `preburn_address`: the coins are moving from + // `preburn_address`'s `Preburn` resource to its balance + deposit(preburn_address, preburn_address, coin, x"", x"", false) + } + spec cancel_burn { + include CancelBurnAbortsIf; + include Diem::CancelBurnWithCapEmits; + include Diem::CancelBurnWithCapEnsures; + include DepositEnsures{payee: preburn_address}; + include DepositEmits{ + payer: preburn_address, + payee: preburn_address, + amount: amount, + metadata: x"" + }; + } + spec schema CancelBurnAbortsIf { + account: signer; + preburn_address: address; + amount: u64; + include Diem::CancelBurnAbortsIf; + include DepositAbortsIf{ + payer: preburn_address, + payee: preburn_address, + amount: amount, + metadata: x"", + }; + include DepositOverflowAbortsIf{payee: preburn_address, amount: amount}; + } + + /// Helper to withdraw `amount` from the given account balance and return the withdrawn Diem + fun withdraw_from_balance( + payer: address, + payee: address, + balance: &mut Balance, + amount: u64 + ): Diem acquires AccountOperationsCapability { + DiemTimestamp::assert_operating(); + AccountFreezing::assert_not_frozen(payer); + // Make sure that this withdrawal is compliant with the limits on + // the account if it's a inter-VASP transfer, + if (should_track_limits_for_account(payer, payee, true)) { + let can_withdraw = AccountLimits::update_withdrawal_limits( + amount, + VASP::parent_address(payer), + &borrow_global(@DiemRoot).limits_cap + ); + assert!(can_withdraw, errors::limit_exceeded(EWITHDRAWAL_EXCEEDS_LIMITS)); + }; + let coin = &mut balance.coin; + // Abort if this withdrawal would make the `payer`'s balance go negative + assert!(Diem::value(coin) >= amount, errors::limit_exceeded(EINSUFFICIENT_BALANCE)); + Diem::withdraw(coin, amount) + } + spec withdraw_from_balance { + modifies global>(VASP::spec_parent_address(payer)); + include WithdrawFromBalanceAbortsIf; + include WithdrawFromBalanceEnsures; + } + spec schema WithdrawFromBalanceAbortsIf { + payer: address; + payee: address; + balance: Balance; + amount: u64; + include WithdrawFromBalanceNoLimitsAbortsIf; + include + spec_should_track_limits_for_account(payer, payee, true) ==> + AccountLimits::UpdateWithdrawalLimitsAbortsIf { + addr: VASP::spec_parent_address(payer), + }; + aborts_if + spec_should_track_limits_for_account(payer, payee, true) && + ( !spec_has_account_operations_cap() || + !AccountLimits::spec_update_withdrawal_limits(amount, VASP::spec_parent_address(payer)) + ) + with errors::LIMIT_EXCEEDED; + } + spec schema WithdrawFromBalanceNoLimitsAbortsIf { + payer: address; + payee: address; + balance: Balance; + amount: u64; + include DiemTimestamp::AbortsIfNotOperating; + include AccountFreezing::AbortsIfFrozen{account: payer}; + aborts_if balance.coin.value < amount with errors::LIMIT_EXCEEDED; + } + spec schema WithdrawFromBalanceEnsures { + balance: Balance; + amount: u64; + result: Diem; + ensures balance.coin.value == old(balance.coin.value) - amount; + ensures result.value == amount; + } + + /// Withdraw `amount` `Diem`'s from the account balance under + /// `cap.account_address` + fun withdraw_from( + cap: &WithdrawCapability, + payee: address, + amount: u64, + metadata: vector, + ): Diem acquires Balance, AccountOperationsCapability, DiemAccount { + DiemTimestamp::assert_operating(); + let payer = cap.account_address; + assert!(exists_at(payer), errors::not_published(EACCOUNT)); + assert!(exists>(payer), errors::not_published(EPAYER_DOESNT_HOLD_CURRENCY)); + let account_balance = borrow_global_mut>(payer); + // Load the payer's account and emit an event to record the withdrawal + event::emit_event( + &mut borrow_global_mut(payer).sent_events, + SentPaymentEvent { + amount, + currency_code: Diem::currency_code(), + payee, + metadata + }, + ); + withdraw_from_balance(payer, payee, account_balance, amount) + } + spec withdraw_from { + let payer = cap.account_address; + modifies global>(payer); + modifies global(payer); + modifies global>(VASP::spec_parent_address(payer)); + ensures exists(payer); + ensures global(payer).withdraw_capability + == old(global(payer).withdraw_capability); + ensures event::spec_guid_eq(global(payer).sent_events, + old(global(payer).sent_events)); + ensures event::spec_guid_eq(global(payer).received_events, + old(global(payer).received_events)); + include WithdrawFromAbortsIf; + include WithdrawFromBalanceEnsures{balance: global>(payer)}; + include WithdrawOnlyFromCapAddress; + include WithdrawFromEmits; + } + spec schema WithdrawFromAbortsIf { + cap: WithdrawCapability; + payee: address; + amount: u64; + let payer = cap.account_address; + include DiemTimestamp::AbortsIfNotOperating; + include Diem::AbortsIfNoCurrency; + include WithdrawFromBalanceAbortsIf{payer, balance: global>(payer)}; + aborts_if !exists_at(payer) with errors::NOT_PUBLISHED; + aborts_if !exists>(payer) with errors::NOT_PUBLISHED; + } + /// # Access Control + spec schema WithdrawOnlyFromCapAddress { + cap: WithdrawCapability; + /// Can only withdraw from the balances of cap.account_address [[H19]][PERMISSION]. + ensures forall addr: address where old(exists>(addr)) && addr != cap.account_address: + balance(addr) == old(balance(addr)); + } + spec schema WithdrawFromEmits { + cap: WithdrawCapability; + payee: address; + amount: u64; + metadata: vector; + let payer = cap.account_address; + let handle = global(payer).sent_events; + let msg = SentPaymentEvent { + amount, + currency_code: Diem::spec_currency_code(), + payee, + metadata + }; + emits msg to handle; + } + + /// Withdraw `amount` `Diem`'s from `cap.address` and send them to the `Preburn` + /// resource under `dd`. + public fun preburn( + dd: &signer, + cap: &WithdrawCapability, + amount: u64 + ) acquires Balance, AccountOperationsCapability, DiemAccount { + Roles::assert_designated_dealer(dd); + DiemTimestamp::assert_operating(); + Diem::preburn_to(dd, withdraw_from(cap, signer::address_of(dd), amount, x"")) + } + spec preburn { + pragma opaque; + let dd_addr = signer::address_of(dd); + let payer = cap.account_address; + modifies global>(VASP::spec_parent_address(payer)); + modifies global(payer); + ensures exists(payer); + ensures global(payer).withdraw_capability + == old(global(payer).withdraw_capability); + ensures event::spec_guid_eq(global(payer).sent_events, + old(global(payer).sent_events)); + ensures event::spec_guid_eq(global(payer).received_events, + old(global(payer).received_events)); + ensures event::spec_guid_eq(global(dd_addr).sent_events, + old(global(dd_addr).sent_events)); + ensures event::spec_guid_eq(global(dd_addr).received_events, + old(global(dd_addr).received_events)); + include PreburnAbortsIf; + include PreburnEnsures{dd, payer}; + include PreburnEmits; + } + spec schema PreburnAbortsIf { + dd: signer; + cap: WithdrawCapability; + amount: u64; + include DiemTimestamp::AbortsIfNotOperating{}; + include WithdrawFromAbortsIf{payee: signer::address_of(dd)}; + include Diem::PreburnToAbortsIf{account: dd}; + } + spec schema PreburnEnsures { + dd: signer; + payer: address; + amount: u64; + modifies global>(payer); + let payer_balance = global>(payer).coin.value; + let post post_payer_balance = global>(payer).coin.value; + /// The balance of payer decreases by `amount`. + ensures post_payer_balance == payer_balance - amount; + /// The value of preburn at `dd_addr` increases by `amount`; + include Diem::PreburnToEnsures{amount, account: dd}; + } + spec schema PreburnEmits { + dd: signer; + cap: WithdrawCapability; + amount: u64; + let dd_addr = signer::address_of(dd); + include Diem::PreburnWithResourceEmits{preburn_address: dd_addr}; + include WithdrawFromEmits{payee: dd_addr, metadata: x""}; + } + + /// Return a unique capability granting permission to withdraw from the sender's account balance. + public fun extract_withdraw_capability( + sender: &signer + ): WithdrawCapability acquires DiemAccount { + let sender_addr = signer::address_of(sender); + // Abort if we already extracted the unique withdraw capability for this account. + assert!( + !delegated_withdraw_capability(sender_addr), + errors::invalid_state(EWITHDRAW_CAPABILITY_ALREADY_EXTRACTED) + ); + assert!(exists_at(sender_addr), errors::not_published(EACCOUNT)); + let account = borrow_global_mut(sender_addr); + option::extract(&mut account.withdraw_capability) + } + + spec extract_withdraw_capability { + pragma opaque; + let sender_addr = signer::address_of(sender); + modifies global(sender_addr); + include ExtractWithdrawCapAbortsIf{sender_addr}; + ensures exists(sender_addr); + ensures result == old(spec_get_withdraw_cap(sender_addr)); + ensures global(sender_addr) == update_field(old(global(sender_addr)), + withdraw_capability, option::spec_none()); + ensures result.account_address == sender_addr; + } + + spec schema ExtractWithdrawCapAbortsIf { + sender_addr: address; + aborts_if !exists_at(sender_addr) with errors::NOT_PUBLISHED; + aborts_if spec_holds_delegated_withdraw_capability(sender_addr) with errors::INVALID_STATE; + } + + /// Return the withdraw capability to the account it originally came from + public fun restore_withdraw_capability(cap: WithdrawCapability) + acquires DiemAccount { + assert!(exists_at(cap.account_address), errors::not_published(EACCOUNT)); + // Abort if the withdraw capability for this account is not extracted, + // indicating that the withdraw capability is not unique. + assert!( + delegated_withdraw_capability(cap.account_address), + errors::invalid_state(EWITHDRAW_CAPABILITY_NOT_EXTRACTED) + ); + let account = borrow_global_mut(cap.account_address); + option::fill(&mut account.withdraw_capability, cap) + } + + spec restore_withdraw_capability { + pragma opaque; + let cap_addr = cap.account_address; + modifies global(cap_addr); + ensures global(cap_addr) == update_field(old(global(cap_addr)), + withdraw_capability, option::spec_some(cap)); + aborts_if !exists_at(cap_addr) with errors::NOT_PUBLISHED; + aborts_if !delegated_withdraw_capability(cap_addr) with errors::INVALID_STATE; + ensures spec_holds_own_withdraw_cap(cap_addr); + } + + /// Withdraw `amount` Diem from the address embedded in `WithdrawCapability` and + /// deposits it into the `payee`'s account balance. + /// The included `metadata` will appear in the `SentPaymentEvent` and `ReceivedPaymentEvent`. + /// The `metadata_signature` will only be checked if this payment is subject to the dual + /// attestation protocol + public fun pay_from( + cap: &WithdrawCapability, + payee: address, + amount: u64, + metadata: vector, + metadata_signature: vector + ) acquires DiemAccount, Balance, AccountOperationsCapability { + deposit( + *&cap.account_address, + payee, + withdraw_from(cap, payee, amount, copy metadata), + metadata, + metadata_signature, + true + ); + } + + /// Withdraw `amount` Diem from the address embedded in `WithdrawCapability` and + /// deposits it into the `payee`'s account balance. + /// The included `metadata` will appear in the `SentPaymentEvent` and `ReceivedPaymentEvent`. + /// As `payee` is also signer of the transaction, no metadata signature is required for dual attestation. + public fun pay_by_signers( + cap: &WithdrawCapability, + payee: &signer, + amount: u64, + metadata: vector, + ) acquires DiemAccount, Balance, AccountOperationsCapability { + let payee_address = signer::address_of(payee); + deposit( + *&cap.account_address, + payee_address, + withdraw_from(cap, payee_address, amount, copy metadata), + metadata, + x"", + false + ); + } + + spec pay_from { + pragma opaque; + + include PayFromWithoutDualAttestation{ + payer: cap.account_address + }; + include DualAttestation::AssertPaymentOkAbortsIf{ + payer: cap.account_address, + value: amount + }; + } + + spec pay_by_signers { + pragma opaque; + + include PayFromWithoutDualAttestation{ + payer: cap.account_address, + payee: signer::address_of(payee) + }; + } + + spec schema PayFromWithoutDualAttestation { + payer: address; + payee: address; + amount: u64; + metadata: vector; + + modifies global(payer); + modifies global(payee); + modifies global>(payer); + modifies global>(payee); + modifies global>(VASP::spec_parent_address(payer)); + modifies global>(VASP::spec_parent_address(payee)); + ensures exists_at(payer); + ensures exists_at(payee); + ensures exists>(payer); + ensures exists>(payee); + ensures global(payer).withdraw_capability + == old(global(payer).withdraw_capability); + ensures event::spec_guid_eq(global(payer).sent_events, + old(global(payer).sent_events)); + ensures event::spec_guid_eq(global(payer).received_events, + old(global(payer).received_events)); + ensures event::spec_guid_eq(global(payee).sent_events, + old(global(payee).sent_events)); + ensures event::spec_guid_eq(global(payee).received_events, + old(global(payee).received_events)); + include PayFromAbortsIf; + include PayFromEnsures{payer}; + include PayFromEmits; + } + + spec schema PayFromAbortsIf { + cap: WithdrawCapability; + payee: address; + amount: u64; + metadata: vector; + include DepositAbortsIf{payer: cap.account_address}; + include cap.account_address != payee ==> DepositOverflowAbortsIf; + include WithdrawFromAbortsIf; + } + spec schema PayFromAbortsIfRestricted { + cap: WithdrawCapability; + payee: address; + amount: u64; + metadata: vector; + let payer = cap.account_address; + include DepositAbortsIfRestricted{payer: cap.account_address}; + include WithdrawFromBalanceNoLimitsAbortsIf{payer, balance: global>(payer)}; + aborts_if !exists>(payer) with errors::NOT_PUBLISHED; + } + spec schema PayFromEnsures { + payer: address; + payee: address; + amount: u64; + ensures payer == payee ==> balance(payer) == old(balance(payer)); + ensures payer != payee ==> balance(payer) == old(balance(payer)) - amount; + ensures payer != payee ==> balance(payee) == old(balance(payee)) + amount; + } + spec schema PayFromEmits { + cap: WithdrawCapability; + payee: address; + amount: u64; + metadata: vector; + let payer = cap.account_address; + include DepositEmits{payer: payer}; + include WithdrawFromEmits; + } + + /// Rotate the authentication key for the account under cap.account_address + public fun rotate_authentication_key( + cap: &KeyRotationCapability, + new_authentication_key: vector, + ) acquires DiemAccount { + assert!(exists_at(cap.account_address), errors::not_published(EACCOUNT)); + let sender_account_resource = borrow_global_mut(cap.account_address); + // Don't allow rotating to clearly invalid key + assert!( + vector::length(&new_authentication_key) == 32, + errors::invalid_argument(EMALFORMED_AUTHENTICATION_KEY) + ); + sender_account_resource.authentication_key = new_authentication_key; + } + spec rotate_authentication_key { + include RotateAuthenticationKeyAbortsIf; + include RotateAuthenticationKeyEnsures{addr: cap.account_address}; + include RotateOnlyKeyOfCapAddress; + } + spec schema RotateAuthenticationKeyAbortsIf { + cap: &KeyRotationCapability; + new_authentication_key: vector; + aborts_if !exists_at(cap.account_address) with errors::NOT_PUBLISHED; + aborts_if len(new_authentication_key) != 32 with errors::INVALID_ARGUMENT; + } + spec schema RotateAuthenticationKeyEnsures { + addr: address; + new_authentication_key: vector; + ensures global(addr).authentication_key == new_authentication_key; + } + + /// # Access Control + spec schema RotateOnlyKeyOfCapAddress { + cap: KeyRotationCapability; + /// Can only rotate the authentication_key of cap.account_address [[H18]][PERMISSION]. + ensures forall addr: address where addr != cap.account_address && old(exists_at(addr)): + global(addr).authentication_key == old(global(addr).authentication_key); + } + + /// Return a unique capability granting permission to rotate the sender's authentication key + public fun extract_key_rotation_capability(account: &signer): KeyRotationCapability + acquires DiemAccount { + let account_address = signer::address_of(account); + // Abort if we already extracted the unique key rotation capability for this account. + assert!( + !delegated_key_rotation_capability(account_address), + errors::invalid_state(EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED) + ); + assert!(exists_at(account_address), errors::not_published(EACCOUNT)); + let account = borrow_global_mut(account_address); + option::extract(&mut account.key_rotation_capability) + } + spec extract_key_rotation_capability { + include ExtractKeyRotationCapabilityAbortsIf; + include ExtractKeyRotationCapabilityEnsures; + } + spec schema ExtractKeyRotationCapabilityAbortsIf { + account: signer; + let account_addr = signer::address_of(account); + aborts_if !exists_at(account_addr) with errors::NOT_PUBLISHED; + include AbortsIfDelegatedKeyRotationCapability; + } + spec schema AbortsIfDelegatedKeyRotationCapability { + account: signer; + aborts_if delegated_key_rotation_capability(signer::address_of(account)) with errors::INVALID_STATE; + } + spec schema ExtractKeyRotationCapabilityEnsures { + account: signer; + ensures delegated_key_rotation_capability(signer::address_of(account)); + } + + /// Return the key rotation capability to the account it originally came from + public fun restore_key_rotation_capability(cap: KeyRotationCapability) + acquires DiemAccount { + assert!(exists_at(cap.account_address), errors::not_published(EACCOUNT)); + let account = borrow_global_mut(cap.account_address); + option::fill(&mut account.key_rotation_capability, cap) + } + spec restore_key_rotation_capability { + include RestoreKeyRotationCapabilityAbortsIf; + include RestoreKeyRotationCapabilityEnsures; + } + spec schema RestoreKeyRotationCapabilityAbortsIf { + cap: KeyRotationCapability; + aborts_if !exists_at(cap.account_address) with errors::NOT_PUBLISHED; + aborts_if !delegated_key_rotation_capability(cap.account_address) with option::EOPTION_IS_SET; + } + spec schema RestoreKeyRotationCapabilityEnsures { + cap: KeyRotationCapability; + ensures spec_holds_own_key_rotation_cap(cap.account_address); + } + + /// Add balances for `Token` to `new_account`. If `add_all_currencies` is true, + /// then add for both token types. + fun add_currencies_for_account( + new_account: &signer, + add_all_currencies: bool, + ) { + let new_account_addr = signer::address_of(new_account); + add_currency(new_account); + if (add_all_currencies) { + if (!exists>(new_account_addr)) { + add_currency(new_account); + }; + if (!exists>(new_account_addr)) { + add_currency(new_account); + }; + }; + } + + spec add_currencies_for_account { + let new_account_addr = signer::address_of(new_account); + aborts_if !Roles::spec_can_hold_balance_addr(new_account_addr) with errors::INVALID_ARGUMENT; + aborts_if exists>(new_account_addr) with errors::ALREADY_PUBLISHED; + aborts_if !exists_at(new_account_addr) with errors::NOT_PUBLISHED; + include AddCurrencyForAccountAbortsIf{addr: new_account_addr}; + include AddCurrencyForAccountEnsures{addr: new_account_addr}; + } + + spec schema AddCurrencyForAccountAbortsIf { + addr: address; + add_all_currencies: bool; + include Diem::AbortsIfNoCurrency; + include add_all_currencies && !exists>(addr) + ==> Diem::AbortsIfNoCurrency; + include add_all_currencies && !exists>(addr) + ==> Diem::AbortsIfNoCurrency; + } + + spec schema AddCurrencyForAccountEnsures { + addr: address; + add_all_currencies: bool; + include AddCurrencyEnsures; + include add_all_currencies && !exists>(addr) + ==> AddCurrencyEnsures; + include add_all_currencies && !exists>(addr) + ==> AddCurrencyEnsures; + } + + + /// Creates a new account with account at `new_account_address` with + /// authentication key `auth_key_prefix` | `fresh_address`. + /// Aborts if there is already an account at `new_account_address`. + /// + /// Creating an account at address 0x0 will abort as it is a reserved address for the MoveVM. + fun make_account( + new_account: &signer, + auth_key_prefix: vector, + ) acquires AccountOperationsCapability { + let new_account_addr = signer::address_of(new_account); + // cannot create an account at the reserved address 0x0 + assert!( + new_account_addr != @VMReserved, + errors::invalid_argument(ECANNOT_CREATE_AT_VM_RESERVED) + ); + assert!( + new_account_addr != @DiemFramework, + errors::invalid_argument(ECANNOT_CREATE_AT_CORE_CODE) + ); + + // Construct authentication key. + let authentication_key = create_authentication_key(new_account, auth_key_prefix); + + // Publish AccountFreezing::FreezingBit (initially not frozen) + AccountFreezing::create(new_account); + // The AccountOperationsCapability is published during Genesis, so it should + // always exist. This is a sanity check. + assert!( + exists(@DiemRoot), + errors::not_published(EACCOUNT_OPERATIONS_CAPABILITY) + ); + // Emit the CreateAccountEvent + event::emit_event( + &mut borrow_global_mut(@DiemRoot).creation_events, + CreateAccountEvent { created: new_account_addr, role_id: Roles::get_role_id(new_account_addr) }, + ); + move_to( + new_account, + DiemAccount { + authentication_key, + withdraw_capability: option::some( + WithdrawCapability { + account_address: new_account_addr + }), + key_rotation_capability: option::some( + KeyRotationCapability { + account_address: new_account_addr + }), + received_events: event::new_event_handle(new_account), + sent_events: event::new_event_handle(new_account), + sequence_number: 0, + } + ); + } + spec make_account { + pragma opaque; + // This is called from a context where invariants are disabled + let new_account_addr = signer::address_of(new_account); + requires !exists(new_account_addr); + modifies global(new_account_addr); + modifies global(new_account_addr); + modifies global(new_account_addr); + requires exists(@DiemRoot); + modifies global(@DiemRoot); + ensures exists(@DiemRoot); + // Next requires is needed to prove invariant + // TODO: This may not be necessary now that invariants are disabled in callers. + requires exists(new_account_addr); + include MakeAccountAbortsIf{addr: new_account_addr}; + ensures exists_at(new_account_addr); + ensures AccountFreezing::spec_account_is_not_frozen(new_account_addr); + let account_ops_cap = global(@DiemRoot); + let post post_account_ops_cap = global(@DiemRoot); + ensures post_account_ops_cap == update_field(account_ops_cap, creation_events, account_ops_cap.creation_events); + ensures spec_holds_own_key_rotation_cap(new_account_addr); + ensures spec_holds_own_withdraw_cap(new_account_addr); + include MakeAccountEmits{new_account_address: signer::address_of(new_account)}; + include MakeAccountEnsures{addr: new_account_addr}; + + } + spec schema MakeAccountEnsures { + addr: address; + ensures global(addr).sequence_number == 0; + } + spec schema MakeAccountAbortsIf { + addr: address; + auth_key_prefix: vector; + aborts_if addr == @VMReserved with errors::INVALID_ARGUMENT; + aborts_if addr == @DiemFramework with errors::INVALID_ARGUMENT; + aborts_if exists(addr) with errors::ALREADY_PUBLISHED; + // There is an invariant below that says that there is always an AccountOperationsCapability + // after Genesis, so this can only abort during Genesis. + aborts_if DiemTimestamp::is_genesis() + && !exists(@DiemRoot) + with errors::NOT_PUBLISHED; + include CreateAuthenticationKeyAbortsIf; + // We do not need to specify aborts_if if account already exists, because make_account will + // abort because of a published FreezingBit, first. + } + spec schema MakeAccountEmits { + new_account_address: address; + let post handle = global(@DiemRoot).creation_events; + let post msg = CreateAccountEvent { + created: new_account_address, + role_id: Roles::spec_get_role_id(new_account_address) + }; + emits msg to handle; + } + + /// Construct an authentication key, aborting if the prefix is not valid. + fun create_authentication_key(account: &signer, auth_key_prefix: vector): vector { + let authentication_key = auth_key_prefix; + vector::append( + &mut authentication_key, bcs::to_bytes(signer::borrow_address(account)) + ); + /* + assert!( + vector::length(&authentication_key) == 64, + errors::invalid_argument(EMALFORMED_AUTHENTICATION_KEY) + ); + */ + authentication_key + } + spec create_authentication_key { + /// The specification of this function is abstracted to avoid the complexity of + /// vector concatenation of serialization results. The actual value of the key + /// is assumed to be irrelevant for callers. Instead the uninterpreted function + /// `spec_abstract_create_authentication_key` is used to represent the key value. + /// The aborts behavior is, however, preserved: the caller must provide a + /// key prefix of a specific length. + pragma opaque; + include [abstract] CreateAuthenticationKeyAbortsIf; + ensures [abstract] + result == spec_abstract_create_authentication_key(auth_key_prefix); // && len(result) == 64; + } + spec schema CreateAuthenticationKeyAbortsIf { + auth_key_prefix: vector; + aborts_if 16 + len(auth_key_prefix) != 32 with errors::INVALID_ARGUMENT; + } + spec fun spec_abstract_create_authentication_key(auth_key_prefix: vector): vector; + + + /// Creates the diem root account (during genesis). Publishes the Diem root role, + /// Publishes a SlidingNonce resource, sets up event generator, publishes + /// AccountOperationsCapability, WriteSetManager, and finally makes the account. + fun create_diem_root_account( + auth_key_prefix: vector, + ) acquires AccountOperationsCapability { + DiemTimestamp::assert_genesis(); + let dr_account = create_signer(@DiemRoot); + CoreAddresses::assert_diem_root(&dr_account); + Roles::grant_diem_root_role(&dr_account); + SlidingNonce::publish(&dr_account); + + assert!( + !exists(@DiemRoot), + errors::already_published(EACCOUNT_OPERATIONS_CAPABILITY) + ); + move_to( + &dr_account, + AccountOperationsCapability { + limits_cap: AccountLimits::grant_mutation_capability(&dr_account), + creation_events: event::new_event_handle(&dr_account), + } + ); + assert!( + !exists(@DiemRoot), + errors::already_published(EWRITESET_MANAGER) + ); + move_to( + &dr_account, + DiemWriteSetManager { + upgrade_events: event::new_event_handle(&dr_account), + } + ); + make_account(&dr_account, auth_key_prefix) + } + + spec create_diem_root_account { + pragma disable_invariants_in_body; + pragma opaque; + include CreateDiemRootAccountModifies; + include CreateDiemRootAccountAbortsIf; + include CreateDiemRootAccountEnsures; + include MakeAccountEmits{new_account_address: @DiemRoot}; + } + + spec schema CreateDiemRootAccountModifies { + let dr_addr = @DiemRoot; + modifies global(dr_addr); + modifies global(dr_addr); + modifies global(dr_addr); + modifies global(dr_addr); + modifies global(dr_addr); + modifies global(dr_addr); + modifies global(dr_addr); + } + spec schema CreateDiemRootAccountAbortsIf { + auth_key_prefix: vector; + include DiemTimestamp::AbortsIfNotGenesis; + include Roles::GrantRole{addr: @DiemRoot, role_id: Roles::DIEM_ROOT_ROLE_ID}; + aborts_if exists(@DiemRoot) + with errors::ALREADY_PUBLISHED; + aborts_if exists(@DiemRoot) + with errors::ALREADY_PUBLISHED; + aborts_if exists(@DiemRoot) + with errors::ALREADY_PUBLISHED; + aborts_if exists(@DiemRoot) + with errors::ALREADY_PUBLISHED; + include CreateAuthenticationKeyAbortsIf; + } + spec schema CreateDiemRootAccountEnsures { + let dr_addr = @DiemRoot; + ensures exists(dr_addr); + ensures exists(dr_addr); + ensures exists(dr_addr); + ensures Roles::spec_has_diem_root_role_addr(dr_addr); + ensures exists_at(dr_addr); + ensures AccountFreezing::spec_account_is_not_frozen(dr_addr); + ensures spec_holds_own_key_rotation_cap(dr_addr); + ensures spec_holds_own_withdraw_cap(dr_addr); + } + + /// Create a treasury/compliance account at `new_account_address` with authentication key + /// `auth_key_prefix` | `new_account_address`. Can only be called during genesis. + /// Also, publishes the treasury compliance role, the SlidingNonce resource, and + /// event handle generator, then makes the account. + fun create_treasury_compliance_account( + dr_account: &signer, + auth_key_prefix: vector, + ) acquires AccountOperationsCapability { + DiemTimestamp::assert_genesis(); + Roles::assert_diem_root(dr_account); + let new_account_address = @TreasuryCompliance; + let new_account = create_signer(new_account_address); + Roles::grant_treasury_compliance_role(&new_account, dr_account); + SlidingNonce::publish(&new_account); + VASPDomain::publish_vasp_domain_manager(&new_account); + make_account(&new_account, auth_key_prefix) + } + spec create_treasury_compliance_account { + pragma disable_invariants_in_body; + pragma opaque; + let tc_addr = @TreasuryCompliance; + include CreateTreasuryComplianceAccountModifies; + include CreateTreasuryComplianceAccountAbortsIf; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include MakeAccountAbortsIf{addr: @TreasuryCompliance}; + include CreateTreasuryComplianceAccountEnsures; + let account_ops_cap = global(@DiemRoot); + let post post_account_ops_cap = global(@DiemRoot); + ensures post_account_ops_cap == update_field(account_ops_cap, creation_events, account_ops_cap.creation_events); + include MakeAccountEmits{new_account_address: @TreasuryCompliance}; + aborts_if VASPDomain::tc_domain_manager_exists() with errors::ALREADY_PUBLISHED; + } + spec schema CreateTreasuryComplianceAccountModifies { + let tc_addr = @TreasuryCompliance; + modifies global(tc_addr); + modifies global(tc_addr); + modifies global(tc_addr); + modifies global(tc_addr); + modifies global(@DiemRoot); + ensures exists(@DiemRoot); + modifies global(@TreasuryCompliance); + modifies global(tc_addr); + } + spec schema CreateTreasuryComplianceAccountAbortsIf { + dr_account: signer; + auth_key_prefix: vector; + include DiemTimestamp::AbortsIfNotGenesis; + include Roles::GrantRole{addr: @TreasuryCompliance, role_id: Roles::TREASURY_COMPLIANCE_ROLE_ID}; + aborts_if exists(@TreasuryCompliance) + with errors::ALREADY_PUBLISHED; + aborts_if VASPDomain::tc_domain_manager_exists() with errors::ALREADY_PUBLISHED; + } + spec schema CreateTreasuryComplianceAccountEnsures { + let tc_addr = @TreasuryCompliance; + ensures Roles::spec_has_treasury_compliance_role_addr(tc_addr); + ensures exists_at(tc_addr); + ensures exists(tc_addr); + ensures AccountFreezing::spec_account_is_not_frozen(tc_addr); + ensures spec_holds_own_key_rotation_cap(tc_addr); + ensures spec_holds_own_withdraw_cap(tc_addr); + ensures exists(tc_addr); + } + + /////////////////////////////////////////////////////////////////////////// + // Designated Dealer API + /////////////////////////////////////////////////////////////////////////// + + /// Create a designated dealer account at `new_account_address` with authentication key + /// `auth_key_prefix` | `new_account_address`, for non synthetic CoinType. + /// Creates Preburn resource under account 'new_account_address' + public fun create_designated_dealer( + creator_account: &signer, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + add_all_currencies: bool, + ) acquires AccountOperationsCapability { + DiemTimestamp::assert_operating(); + Roles::assert_treasury_compliance(creator_account); + let new_dd_account = create_signer(new_account_address); + Roles::new_designated_dealer_role(creator_account, &new_dd_account); + DesignatedDealer::publish_designated_dealer_credential(&new_dd_account, creator_account, add_all_currencies); + DualAttestation::publish_credential(&new_dd_account, creator_account, human_name); + make_account(&new_dd_account, auth_key_prefix); + add_currencies_for_account(&new_dd_account, add_all_currencies) + } + + spec create_designated_dealer { + pragma disable_invariants_in_body; + include CreateDesignatedDealerAbortsIf; + include CreateDesignatedDealerEnsures; + include MakeAccountEmits; + } + + spec schema CreateDesignatedDealerAbortsIf { + creator_account: signer; + new_account_address: address; + auth_key_prefix: vector; + add_all_currencies: bool; + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotTreasuryCompliance{account: creator_account}; + aborts_if exists(new_account_address) with errors::ALREADY_PUBLISHED; + aborts_if exists(new_account_address) with errors::ALREADY_PUBLISHED; + include if (add_all_currencies) DesignatedDealer::AddCurrencyAbortsIf{dd_addr: new_account_address} + else DesignatedDealer::AddCurrencyAbortsIf{dd_addr: new_account_address}; + include AddCurrencyForAccountAbortsIf{addr: new_account_address}; + include MakeAccountAbortsIf{addr: new_account_address}; + } + + spec schema CreateDesignatedDealerEnsures { + new_account_address: address; + ensures exists(new_account_address); + ensures exists_at(new_account_address); + ensures Roles::spec_has_designated_dealer_role_addr(new_account_address); + include AddCurrencyForAccountEnsures{addr: new_account_address}; + } + + /////////////////////////////////////////////////////////////////////////// + // VASP methods + /////////////////////////////////////////////////////////////////////////// + + /// Create an account with the ParentVASP role at `new_account_address` with authentication key + /// `auth_key_prefix` | `new_account_address`. If `add_all_currencies` is true, 0 balances for + /// all available currencies in the system will also be added. + public fun create_parent_vasp_account( + creator_account: &signer, // TreasuryCompliance + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + add_all_currencies: bool + ) acquires AccountOperationsCapability { + Roles::assert_treasury_compliance(creator_account); + let new_account = create_signer(new_account_address); + Roles::new_parent_vasp_role(creator_account, &new_account); + VASP::publish_parent_vasp_credential(&new_account, creator_account); + DualAttestation::publish_credential(&new_account, creator_account, human_name); + VASPDomain::publish_vasp_domains(&new_account); + make_account(&new_account, auth_key_prefix); + add_currencies_for_account(&new_account, add_all_currencies); + spec { + assert exists(signer::address_of(new_account)); + assert Roles::spec_has_treasury_compliance_role_addr(signer::address_of(creator_account)); + } + } + + spec create_parent_vasp_account { + pragma disable_invariants_in_body; + include CreateParentVASPAccountAbortsIf; + include CreateParentVASPAccountEnsures; + include MakeAccountEmits; + } + + spec schema CreateParentVASPAccountAbortsIf { + creator_account: signer; + new_account_address: address; + auth_key_prefix: vector; + add_all_currencies: bool; + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotTreasuryCompliance{account: creator_account}; + include VASPDomain::PublishVASPDomainsAbortsIf{vasp_addr: new_account_address}; + aborts_if exists(new_account_address) with errors::ALREADY_PUBLISHED; + aborts_if VASP::is_vasp(new_account_address) with errors::ALREADY_PUBLISHED; + include AddCurrencyForAccountAbortsIf{addr: new_account_address}; + include MakeAccountAbortsIf{addr: new_account_address}; + } + + spec schema CreateParentVASPAccountEnsures { + new_account_address: address; + include VASP::PublishParentVASPEnsures{vasp_addr: new_account_address}; + ensures exists_at(new_account_address); + ensures Roles::spec_has_parent_VASP_role_addr(new_account_address); + include AddCurrencyForAccountEnsures{addr: new_account_address}; + include VASPDomain::PublishVASPDomainsEnsures{ vasp_addr: new_account_address }; + } + + /// Create an account with the ChildVASP role at `new_account_address` with authentication key + /// `auth_key_prefix` | `new_account_address` and a 0 balance of type `Token`. If + /// `add_all_currencies` is true, 0 balances for all avaialable currencies in the system will + /// also be added. This account will be a child of `creator`, which must be a ParentVASP. + public fun create_child_vasp_account( + parent: &signer, + new_account_address: address, + auth_key_prefix: vector, + add_all_currencies: bool, + ) acquires AccountOperationsCapability { + DiemTimestamp::assert_operating(); + Roles::assert_parent_vasp_role(parent); + let new_account = create_signer(new_account_address); + Roles::new_child_vasp_role(parent, &new_account); + VASP::publish_child_vasp_credential( + parent, + &new_account, + ); + make_account(&new_account, auth_key_prefix); + add_currencies_for_account(&new_account, add_all_currencies); + } + spec create_child_vasp_account { + pragma disable_invariants_in_body; + include CreateChildVASPAccountAbortsIf; + include CreateChildVASPAccountEnsures{ + parent_addr: signer::address_of(parent), + child_addr: new_account_address, + }; + include AddCurrencyForAccountEnsures{addr: new_account_address}; + include MakeAccountEmits; + } + spec schema CreateChildVASPAccountAbortsIf { + parent: signer; + new_account_address: address; + auth_key_prefix: vector; + add_all_currencies: bool; + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotParentVasp{account: parent}; + aborts_if exists(new_account_address) with errors::ALREADY_PUBLISHED; + include VASP::PublishChildVASPAbortsIf{child_addr: new_account_address}; + include AddCurrencyForAccountAbortsIf{addr: new_account_address}; + include MakeAccountAbortsIf{addr: new_account_address}; + } + spec schema CreateChildVASPAccountEnsures { + parent_addr: address; + child_addr: address; + add_all_currencies: bool; + include VASP::PublishChildVASPEnsures; + ensures exists_at(child_addr); + ensures Roles::spec_has_child_VASP_role_addr(child_addr); + } + + /////////////////////////////////////////////////////////////////////////// + // General purpose methods + /////////////////////////////////////////////////////////////////////////// + + native fun create_signer(addr: address): signer; + + public fun publish_crsn(account: &signer, size: u64) + acquires DiemAccount { + let account_state = borrow_global(signer::address_of(account)); + // Don't set this to start at account_state.sequence_number + 1, since + // after this the epilogue will record the sequence nonce + // `account_state.sequence_number` which will shift the window. + // If we set the window to start at `account_state.sequence_number + + // 1`, this transaction would be rejected in the epilogue as the + // sequence nonce would be outside of the window. + CRSN::publish(account, account_state.sequence_number, size) + } + + /// Helper to return the u64 value of the `balance` for `account` + fun balance_for(balance: &Balance): u64 { + Diem::value(&balance.coin) + } + + /// Return the current balance of the account at `addr`. + public fun balance(addr: address): u64 acquires Balance { + assert!(exists>(addr), errors::not_published(EPAYER_DOESNT_HOLD_CURRENCY)); + balance_for(borrow_global>(addr)) + } + spec balance { + aborts_if !exists>(addr) with errors::NOT_PUBLISHED; + } + + /// Add a balance of `Token` type to the sending account + public(friend) fun add_currency(account: &signer) { + let addr = signer::address_of(account); + // aborts if `Token` is not a currency type in the system + Diem::assert_is_currency(); + assert!(exists_at(addr), errors::not_published(EACCOUNT)); + // Check that an account with this role is allowed to hold funds + assert!( + Roles::can_hold_balance(account), + errors::invalid_argument(EROLE_CANT_STORE_BALANCE) + ); + // aborts if this account already has a balance in `Token` + assert!( + !exists>(addr), + errors::already_published(EADD_EXISTING_CURRENCY) + ); + + move_to(account, Balance{ coin: Diem::zero() }) + } + spec add_currency { + /// An account must exist at the address + let addr = signer::address_of(account); + aborts_if !exists_at(addr) with errors::NOT_PUBLISHED; + include AddCurrencyAbortsIf; + include AddCurrencyEnsures; + } + spec schema AddCurrencyAbortsIf { + account: signer; + /// `Currency` must be valid + include Diem::AbortsIfNoCurrency; + /// `account` cannot have an existing balance in `Currency` + aborts_if exists>(signer::address_of(account)) with errors::ALREADY_PUBLISHED; + /// `account` must be allowed to hold balances. + include AbortsIfAccountCantHoldBalance; + } + + spec schema AddCurrencyEnsures { + addr: address; + /// This publishes a `Balance` to the caller's account + ensures exists>(addr); + ensures global>(addr) + == Balance{ coin: Diem { value: 0 } }; + } + + // #[test_only] TODO: uncomment once unit tests are fully migrated + public fun add_currency_for_test(account: &signer) { + add_currency(account) + } + spec add_currency_for_test { + pragma verify = false; + } + + /// # Access Control + spec schema AbortsIfAccountCantHoldBalance { + account: signer; + /// This function must abort if the predicate `can_hold_balance` for `account` returns false + /// [[D1]][ROLE][[D2]][ROLE][[D3]][ROLE][[D4]][ROLE][[D5]][ROLE][[D6]][ROLE][[D7]][ROLE]. + aborts_if !Roles::can_hold_balance(account) with errors::INVALID_ARGUMENT; + } + + /// Return whether the account at `addr` accepts `Token` type coins + public fun accepts_currency(addr: address): bool { + exists>(addr) + } + + /// Helper to return the sequence number field for given `account` + fun sequence_number_for_account(account: &DiemAccount): u64 { + account.sequence_number + } + + /// Return the current sequence number at `addr` + public fun sequence_number(addr: address): u64 acquires DiemAccount { + assert!(exists_at(addr), errors::not_published(EACCOUNT)); + sequence_number_for_account(borrow_global(addr)) + } + + /// Return the authentication key for this account + public fun authentication_key(addr: address): vector acquires DiemAccount { + assert!(exists_at(addr), errors::not_published(EACCOUNT)); + *&borrow_global(addr).authentication_key + } + + /// Return true if the account at `addr` has delegated its key rotation capability + public fun delegated_key_rotation_capability(addr: address): bool + acquires DiemAccount { + assert!(exists_at(addr), errors::not_published(EACCOUNT)); + option::is_none(&borrow_global(addr).key_rotation_capability) + } + + /// Return true if the account at `addr` has delegated its withdraw capability + public fun delegated_withdraw_capability(addr: address): bool + acquires DiemAccount { + assert!(exists_at(addr), errors::not_published(EACCOUNT)); + option::is_none(&borrow_global(addr).withdraw_capability) + } + + /// Return a reference to the address associated with the given withdraw capability + public fun withdraw_capability_address(cap: &WithdrawCapability): &address { + &cap.account_address + } + + /// Return a reference to the address associated with the given key rotation capability + public fun key_rotation_capability_address(cap: &KeyRotationCapability): &address { + &cap.account_address + } + + /// Checks if an account exists at `check_addr` + public fun exists_at(check_addr: address): bool { + exists(check_addr) + } + + /////////////////////////////////////////////////////////////////////////// + // Prologues and Epilogues of user signed transactions + /////////////////////////////////////////////////////////////////////////// + + /// The prologue for module transaction + fun module_prologue( + sender: signer, + txn_sequence_number: u64, + txn_public_key: vector, + txn_gas_price: u64, + txn_max_gas_units: u64, + txn_expiration_time: u64, + chain_id: u8, + ) acquires DiemAccount, Balance { + assert!( + DiemTransactionPublishingOption::is_module_allowed(&sender), + errors::invalid_state(PROLOGUE_EMODULE_NOT_ALLOWED), + ); + + prologue_common( + &sender, + txn_sequence_number, + txn_public_key, + txn_gas_price, + txn_max_gas_units, + txn_expiration_time, + chain_id, + ) + } + spec module_prologue { + let transaction_sender = signer::address_of(sender); + let max_transaction_fee = txn_gas_price * txn_max_gas_units; + include ModulePrologueAbortsIf { + max_transaction_fee, + txn_expiration_time_seconds: txn_expiration_time, + }; + ensures prologue_guarantees(sender); + } + spec schema ModulePrologueAbortsIf { + sender: signer; + txn_sequence_number: u64; + txn_public_key: vector; + chain_id: u8; + max_transaction_fee: u128; + txn_expiration_time_seconds: u64; + let transaction_sender = signer::address_of(sender); + include PrologueCommonAbortsIf { + transaction_sender, + txn_sequence_number, + txn_public_key, + chain_id, + max_transaction_fee, + txn_expiration_time_seconds, + }; + /// Aborts only in genesis. Does not need to be handled. + include DiemTransactionPublishingOption::AbortsIfNoTransactionPublishingOption; + /// Covered: L75 (Match 9) + aborts_if !DiemTransactionPublishingOption::spec_is_module_allowed(sender) with errors::INVALID_STATE; + } + + /// The prologue for script transaction + fun script_prologue( + sender: signer, + txn_sequence_number: u64, + txn_public_key: vector, + txn_gas_price: u64, + txn_max_gas_units: u64, + txn_expiration_time: u64, + chain_id: u8, + script_hash: vector, + ) acquires DiemAccount, Balance { + assert!( + DiemTransactionPublishingOption::is_script_allowed(&sender, &script_hash), + errors::invalid_state(PROLOGUE_ESCRIPT_NOT_ALLOWED), + ); + + prologue_common( + &sender, + txn_sequence_number, + txn_public_key, + txn_gas_price, + txn_max_gas_units, + txn_expiration_time, + chain_id, + ) + } + spec script_prologue { + let transaction_sender = signer::address_of(sender); + let max_transaction_fee = txn_gas_price * txn_max_gas_units; + include ScriptPrologueAbortsIf{ + max_transaction_fee, + txn_expiration_time_seconds: txn_expiration_time, + }; + ensures prologue_guarantees(sender); + } + spec schema ScriptPrologueAbortsIf { + sender: signer; + txn_sequence_number: u64; + txn_public_key: vector; + chain_id: u8; + max_transaction_fee: u128; + txn_expiration_time_seconds: u64; + script_hash: vector; + let transaction_sender = signer::address_of(sender); + include PrologueCommonAbortsIf {transaction_sender}; + /// Aborts only in Genesis. Does not need to be handled. + include DiemTransactionPublishingOption::AbortsIfNoTransactionPublishingOption; + /// Covered: L74 (Match 8) + aborts_if !DiemTransactionPublishingOption::spec_is_script_allowed(sender, script_hash) with errors::INVALID_STATE; + } + + /// The prologue for WriteSet transaction + fun writeset_prologue( + sender: signer, + txn_sequence_number: u64, + txn_public_key: vector, + txn_expiration_time: u64, + chain_id: u8, + ) acquires DiemAccount, Balance { + assert!( + signer::address_of(&sender) == @DiemRoot, + errors::invalid_argument(PROLOGUE_EINVALID_WRITESET_SENDER) + ); + assert!(Roles::has_diem_root_role(&sender), errors::invalid_argument(PROLOGUE_EINVALID_WRITESET_SENDER)); + + // Currency code don't matter here as it won't be charged anyway. Gas constants are ommitted. + prologue_common( + &sender, + txn_sequence_number, + txn_public_key, + 0, + 0, + txn_expiration_time, + chain_id, + ) + } + + spec writeset_prologue { + include WritesetPrologueAbortsIf {txn_expiration_time_seconds: txn_expiration_time}; + ensures prologue_guarantees(sender); + ensures Roles::has_diem_root_role(sender); + } + + spec schema WritesetPrologueAbortsIf { + sender: signer; + txn_sequence_number: u64; + txn_public_key: vector; + txn_expiration_time_seconds: u64; + chain_id: u8; + let transaction_sender = signer::address_of(sender); + /// Covered: L146 (Match 0) + aborts_if transaction_sender != @DiemRoot with errors::INVALID_ARGUMENT; + /// Must abort if the signer does not have the DiemRoot role [[H9]][PERMISSION]. + /// Covered: L146 (Match 0) + aborts_if !Roles::spec_has_diem_root_role_addr(transaction_sender) with errors::INVALID_ARGUMENT; + include PrologueCommonAbortsIf{ + transaction_sender, + max_transaction_fee: 0, + }; + } + + fun check_secondary_signers( + secondary_signer_addresses: vector
, + secondary_signer_public_key_hashes: vector>, + ) acquires DiemAccount { + let num_secondary_signers = vector::length(&secondary_signer_addresses); + + // Number of public key hashes must match the number of secondary signers. + assert!( + vector::length(&secondary_signer_public_key_hashes) == num_secondary_signers, + errors::invalid_argument(PROLOGUE_ESECONDARY_KEYS_ADDRESSES_COUNT_MISMATCH), + ); + + // Check validity of the secondary signers' addresses and public keys + let i = 0; + while ({ + spec { + invariant forall j in 0..i: exists_at(secondary_signer_addresses[j]); + invariant forall j in 0..i: secondary_signer_public_key_hashes[j] + == global(secondary_signer_addresses[j]).authentication_key; + }; + (i < num_secondary_signers) + }) + { + // Check that all secondary signers have accounts. + let secondary_address = *vector::borrow(&secondary_signer_addresses, i); + assert!(exists_at(secondary_address), errors::invalid_argument(PROLOGUE_EACCOUNT_DNE)); + + // Check that for each secondary signer, the provided public key hash is equal to the + // authentication key stored on-chain. + let signer_account = borrow_global(secondary_address); + let signer_public_key_hash = *vector::borrow(&secondary_signer_public_key_hashes, i); + assert!( + signer_public_key_hash == *&signer_account.authentication_key, + errors::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), + ); + i = i + 1; + }; + } + spec check_secondary_signers { + pragma opaque; + // NOTE: this is to force the prover to honor the "opaque" pragma in the ignore opaque setting + ensures [concrete] true; + + include CheckSecondarySignersAbortsIf; + let num_secondary_signers = len(secondary_signer_addresses); + ensures forall j in 0..num_secondary_signers: exists_at(secondary_signer_addresses[j]); + ensures forall j in 0..num_secondary_signers: secondary_signer_public_key_hashes[j] + == global(secondary_signer_addresses[j]).authentication_key; + } + spec schema CheckSecondarySignersAbortsIf { + secondary_signer_addresses: vector
; + secondary_signer_public_key_hashes: vector>; + let num_secondary_signers = len(secondary_signer_addresses); + aborts_if len(secondary_signer_public_key_hashes) != num_secondary_signers + with errors::INVALID_ARGUMENT; + aborts_if exists i in 0..num_secondary_signers: !exists_at(secondary_signer_addresses[i]) + with errors::INVALID_ARGUMENT; + aborts_if exists i in 0..num_secondary_signers: + secondary_signer_public_key_hashes[i] != global(secondary_signer_addresses[i]).authentication_key + with errors::INVALID_ARGUMENT; + } + + /// The prologue for multi-agent user transactions + fun multi_agent_script_prologue( + sender: signer, + txn_sequence_number: u64, + txn_sender_public_key: vector, + secondary_signer_addresses: vector
, + secondary_signer_public_key_hashes: vector>, + txn_gas_price: u64, + txn_max_gas_units: u64, + txn_expiration_time: u64, + chain_id: u8, + ) acquires DiemAccount, Balance { + check_secondary_signers( + secondary_signer_addresses, + secondary_signer_public_key_hashes + ); + prologue_common( + &sender, + txn_sequence_number, + txn_sender_public_key, + txn_gas_price, + txn_max_gas_units, + txn_expiration_time, + chain_id, + ) + } + spec multi_agent_script_prologue { + let transaction_sender = signer::address_of(sender); + let max_transaction_fee = txn_gas_price * txn_max_gas_units; + include MultiAgentScriptPrologueAbortsIf{ + max_transaction_fee, + txn_expiration_time_seconds: txn_expiration_time, + }; + ensures prologue_guarantees(sender); + } + + spec schema MultiAgentScriptPrologueAbortsIf { + sender: signer; + txn_sequence_number: u64; + txn_sender_public_key: vector; + secondary_signer_addresses: vector
; + secondary_signer_public_key_hashes: vector>; + chain_id: u8; + max_transaction_fee: u128; + txn_expiration_time_seconds: u64; + include CheckSecondarySignersAbortsIf; + let transaction_sender = signer::address_of(sender); + include PrologueCommonAbortsIf {transaction_sender, txn_public_key: txn_sender_public_key}; + } + + /// The common prologue is invoked at the beginning of every transaction + /// The main properties that it verifies: + /// - The account's auth key matches the transaction's public key + /// - That the account has enough balance to pay for all of the gas + /// - That the sequence number matches the transaction's sequence key + fun prologue_common( + sender: &signer, + txn_sequence_number: u64, + txn_public_key: vector, + txn_gas_price: u64, + txn_max_gas_units: u64, + txn_expiration_time_seconds: u64, + chain_id: u8, + ) acquires DiemAccount, Balance { + let transaction_sender = signer::address_of(sender); + + // [PCA1]: Check that the chain ID stored on-chain matches the chain ID specified by the transaction + assert!(ChainId::get() == chain_id, errors::invalid_argument(PROLOGUE_EBAD_CHAIN_ID)); + + // [PCA2]: Verify that the transaction sender's account exists + assert!(exists_at(transaction_sender), errors::invalid_argument(PROLOGUE_EACCOUNT_DNE)); + + // [PCA3]: We check whether this account is frozen, if it is no transaction can be sent from it. + assert!( + !AccountFreezing::account_is_frozen(transaction_sender), + errors::invalid_state(PROLOGUE_EACCOUNT_FROZEN) + ); + + // Load the transaction sender's account + let sender_account = borrow_global(transaction_sender); + + // [PCA4]: Check that the hash of the transaction's public key matches the account's auth key + assert!( + hash::sha3_256(txn_public_key) == *&sender_account.authentication_key, + errors::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), + ); + + // [PCA5]: Check that the max transaction fee does not overflow a u64 value. + assert!( + (txn_gas_price as u128) * (txn_max_gas_units as u128) <= MAX_U64, + errors::invalid_argument(PROLOGUE_ECANT_PAY_GAS_DEPOSIT), + ); + + let max_transaction_fee = txn_gas_price * txn_max_gas_units; + + // Don't grab the balance if the transaction fee is zero + if (max_transaction_fee > 0) { + // [PCA6]: Check that the gas fee can be paid in this currency + assert!( + TransactionFee::is_coin_initialized(), + errors::invalid_argument(PROLOGUE_EBAD_TRANSACTION_FEE_CURRENCY) + ); + // [PCA7]: Check that the account has a balance in this currency + assert!( + exists>(transaction_sender), + errors::invalid_argument(PROLOGUE_ECANT_PAY_GAS_DEPOSIT) + ); + let balance_amount = balance(transaction_sender); + // [PCA8]: Check that the account can cover the maximum transaction fee + assert!( + balance_amount >= max_transaction_fee, + errors::invalid_argument(PROLOGUE_ECANT_PAY_GAS_DEPOSIT) + ); + }; + + // [PCA9]: Check that the transaction hasn't expired + assert!( + DiemTimestamp::now_seconds() < txn_expiration_time_seconds, + errors::invalid_argument(PROLOGUE_ETRANSACTION_EXPIRED) + ); + + // [PCA10]: Check that the transaction's sequence number will not overflow. + assert!( + (txn_sequence_number as u128) < MAX_U64, + errors::limit_exceeded(PROLOGUE_ESEQUENCE_NUMBER_TOO_BIG) + ); + + if (CRSN::has_crsn(transaction_sender)) { + // [PCA13]: If using a sequence nonce check that it's accepted + assert!( + CRSN::check(sender, txn_sequence_number), + errors::invalid_argument(PROLOGUE_ESEQ_NONCE_INVALID) + ); + } else { + // [PCA11]: Check that the transaction sequence number is not too old (in the past) + assert!( + txn_sequence_number >= sender_account.sequence_number, + errors::invalid_argument(PROLOGUE_ESEQUENCE_NUMBER_TOO_OLD) + ); + + // [PCA12]: Check that the transaction's sequence number matches the + // current sequence number. Otherwise sequence number is too new by [PCA11]. + assert!( + txn_sequence_number == sender_account.sequence_number, + errors::invalid_argument(PROLOGUE_ESEQUENCE_NUMBER_TOO_NEW) + ); + + // WARNING: No checks should be added here as the sequence number too new check should be the last check run + // by the prologue. + } + } + spec prologue_common { + let transaction_sender = signer::address_of(sender); + let max_transaction_fee = txn_gas_price * txn_max_gas_units; + include PrologueCommonAbortsIf { + transaction_sender, + max_transaction_fee, + }; + } + spec schema PrologueCommonAbortsIf { + transaction_sender: address; + txn_sequence_number: u64; + txn_public_key: vector; + chain_id: u8; + max_transaction_fee: u128; + txn_expiration_time_seconds: u64; + /// Only happens if this is called in Genesis. Doesn't need to be handled. + include DiemTimestamp::AbortsIfNotOperating; + /// [PCA1] Covered: L73 (Match 7) + aborts_if chain_id != ChainId::spec_get_chain_id() with errors::INVALID_ARGUMENT; + /// [PCA2] Covered: L65 (Match 4) + aborts_if !exists_at(transaction_sender) with errors::INVALID_ARGUMENT; + /// [PCA3] Covered: L57 (Match 0) + aborts_if AccountFreezing::spec_account_is_frozen(transaction_sender) with errors::INVALID_STATE; + /// [PCA4] Covered: L59 (Match 1) + aborts_if hash::sha3_256(txn_public_key) != global(transaction_sender).authentication_key with errors::INVALID_ARGUMENT; + /// [PCA5] Covered: L69 (Match 5) + aborts_if max_transaction_fee > MAX_U64 with errors::INVALID_ARGUMENT; + /// [PCA6] Covered: L69 (Match 5) + aborts_if max_transaction_fee > 0 && !TransactionFee::is_coin_initialized() with errors::INVALID_ARGUMENT; + /// [PCA7] Covered: L69 (Match 5) + aborts_if max_transaction_fee > 0 && !exists>(transaction_sender) with errors::INVALID_ARGUMENT; + /// [PCA8] Covered: L69 (Match 5) + aborts_if max_transaction_fee > 0 && balance(transaction_sender) < max_transaction_fee with errors::INVALID_ARGUMENT; + /// [PCA9] Covered: L72 (Match 6) + aborts_if DiemTimestamp::spec_now_seconds() >= txn_expiration_time_seconds with errors::INVALID_ARGUMENT; + /// [PCA10] Covered: L81 (match 11) + aborts_if txn_sequence_number >= MAX_U64 with errors::LIMIT_EXCEEDED; + /// [PCA11] Covered: L61 (Match 2) + aborts_if !CRSN::has_crsn(transaction_sender) && txn_sequence_number < global(transaction_sender).sequence_number with errors::INVALID_ARGUMENT; + /// [PCA12] Covered: L63 (match 3) + aborts_if !CRSN::has_crsn(transaction_sender) && txn_sequence_number > global(transaction_sender).sequence_number with errors::INVALID_ARGUMENT; + /// [PCA13] Covered: L93 (match 14) + aborts_if CRSN::has_crsn(transaction_sender) && !CRSN::spec_check(transaction_sender, txn_sequence_number) with errors::INVALID_ARGUMENT; + } + + /// Collects gas and bumps the sequence number for executing a transaction. + /// The epilogue is invoked at the end of the transaction. + /// If the exection of the epilogue fails, it is re-invoked with different arguments, and + /// based on the conditions checked in the prologue, should never fail. + fun epilogue( + account: signer, + txn_sequence_number: u64, + txn_gas_price: u64, + txn_max_gas_units: u64, + gas_units_remaining: u64 + ) acquires DiemAccount, Balance { + epilogue_common( + &account, + txn_sequence_number, + txn_gas_price, + txn_max_gas_units, + gas_units_remaining, + ) + } + spec epilogue { + pragma verify=false; // TODO: time out + include EpilogueCommonAbortsIf; + include EpilogueCommonEnsures; + } + + fun epilogue_common( + account: &signer, + txn_sequence_number: u64, + txn_gas_price: u64, + txn_max_gas_units: u64, + gas_units_remaining: u64 + ) acquires DiemAccount, Balance { + let sender = signer::address_of(account); + + // [EA1; Invariant]: Make sure that the transaction's `max_gas_units` is greater + // than the number of gas units remaining after execution. + assert!(txn_max_gas_units >= gas_units_remaining, errors::invalid_argument(EGAS)); + let gas_used = txn_max_gas_units - gas_units_remaining; + + // [EA2; Invariant]: Make sure that the transaction fee would not overflow maximum + // number representable in a u64. Already checked in [PCA5]. + assert!( + (txn_gas_price as u128) * (gas_used as u128) <= MAX_U64, + errors::limit_exceeded(EGAS) + ); + let transaction_fee_amount = txn_gas_price * gas_used; + + // [EA3; Invariant]: Make sure that account exists, and load the + // transaction sender's account. Already checked in [PCA2]. + assert!(exists_at(sender), errors::not_published(EACCOUNT)); + let sender_account = borrow_global_mut(sender); + + // [EA4; Condition]: Make sure account's sequence number is within the + // representable range of u64. Already checked in [PCA10]. + assert!( + sender_account.sequence_number < (MAX_U64 as u64), + errors::limit_exceeded(PROLOGUE_ESEQUENCE_NUMBER_TOO_BIG) + ); + + if (CRSN::has_crsn(sender)) { + // Make sure the `sender_account`'s CRSN is still valid and record it. + assert!( + CRSN::record(account, txn_sequence_number), + errors::invalid_argument(PROLOGUE_ESEQ_NONCE_INVALID), + ); + } else { + // [EA4; Invariant]: Make sure passed-in `txn_sequence_number` matches + // the `sender_account`'s `sequence_number`. Already checked in [PCA12]. + assert!( + sender_account.sequence_number == txn_sequence_number, + errors::invalid_argument(PROLOGUE_ESEQUENCE_NUMBER_TOO_NEW) + ); + }; + + // The transaction sequence number is passed in to prevent any + // possibility of the account's sequence number increasing by more than + // one for any transaction. + sender_account.sequence_number = sender_account.sequence_number + 1; + + if (transaction_fee_amount > 0) { + // [Invariant Use]: Balance for `Token` verified to exist for non-zero transaction fee amounts by [PCA7]. + let sender_balance = borrow_global_mut>(sender); + let coin = &mut sender_balance.coin; + + // [EA4; Condition]: Abort if this withdrawal would make the `sender_account`'s balance go negative + assert!( + transaction_fee_amount <= Diem::value(coin), + errors::limit_exceeded(PROLOGUE_ECANT_PAY_GAS_DEPOSIT) + ); + + // NB: `withdraw_from_balance` is not used as limits do not apply to this transaction fee + TransactionFee::pay_fee(Diem::withdraw(coin, transaction_fee_amount)) + } + } + spec epilogue_common { + pragma verify=false; // TODO: time out + include EpilogueCommonAbortsIf; + include EpilogueCommonEnsures; + } + spec schema EpilogueCommonAbortsIf { + account: signer; + txn_sequence_number: u64; + txn_gas_price: u64; + txn_max_gas_units: u64; + gas_units_remaining: u64; + let sender = signer::address_of(account); + let sender_account = global(sender); + let gas_used = txn_max_gas_units - gas_units_remaining; + let transaction_fee_amount = txn_gas_price * gas_used; + let coin = global>(sender).coin; + /// [EA1; Invariant] + aborts_if txn_max_gas_units < gas_units_remaining with errors::INVALID_ARGUMENT; + /// [EA2; Invariant] + aborts_if txn_gas_price * gas_used > MAX_U64 with errors::LIMIT_EXCEEDED; + /// [EA3; Invariant] + aborts_if !exists_at(sender) with errors::NOT_PUBLISHED; + /// [EA4; Condition] + aborts_if sender_account.sequence_number >= MAX_U64 with errors::LIMIT_EXCEEDED; + /// [EA4; Invariant] + aborts_if !CRSN::has_crsn(sender) && (sender_account.sequence_number != txn_sequence_number) with errors::INVALID_ARGUMENT; + /// [PCA7] + aborts_if (transaction_fee_amount > 0) && !exists>(sender); + /// [EA4; Condition] + aborts_if (transaction_fee_amount > 0) && transaction_fee_amount > Diem::value(coin) with errors::LIMIT_EXCEEDED; + include (transaction_fee_amount > 0) ==> TransactionFee::PayFeeAbortsIf{coin: Diem{value: transaction_fee_amount}}; + } + spec schema EpilogueCommonEnsures { + account: signer; + txn_sequence_number: u64; + txn_gas_price: u64; + txn_max_gas_units: u64; + gas_units_remaining: u64; + let sender = signer::address_of(account); + let sender_account = global(sender); + let gas_used = txn_max_gas_units - gas_units_remaining; + let transaction_fee_amount = txn_gas_price * gas_used; + let coin = global>(sender).coin; + ensures global(sender).sequence_number == old(global(sender).sequence_number) + 1; + include (transaction_fee_amount > 0) ==> TransactionFee::PayFeeEnsures{coin: Diem{value: transaction_fee_amount}}; + } + + /// Epilogue for WriteSet trasnaction + fun writeset_epilogue( + dr_account: signer, + txn_sequence_number: u64, + should_trigger_reconfiguration: bool, + ) acquires DiemWriteSetManager, DiemAccount, Balance { + let dr_account = &dr_account; + let writeset_events_ref = borrow_global_mut(@DiemRoot); + event::emit_event( + &mut writeset_events_ref.upgrade_events, + AdminTransactionEvent { committed_timestamp_secs: DiemTimestamp::now_seconds() }, + ); + + // Double check that the sender is the DiemRoot account at the `@DiemRoot` + assert!( + signer::address_of(dr_account) == @DiemRoot, + errors::invalid_argument(PROLOGUE_EINVALID_WRITESET_SENDER) + ); + assert!( + Roles::has_diem_root_role(dr_account), + errors::invalid_argument(PROLOGUE_EINVALID_WRITESET_SENDER) + ); + + // Currency code don't matter here as it won't be charged anyway. + epilogue_common(dr_account, txn_sequence_number, 0, 0, 0); + if (should_trigger_reconfiguration) DiemConfig::reconfigure(dr_account) + } + spec writeset_epilogue { + include WritesetEpilogueAbortsIf; + include EpilogueCommonEnsures{account: dr_account, txn_gas_price: 0, txn_max_gas_units: 0, gas_units_remaining: 0}; + include WritesetEpilogueEmits; + } + spec schema WritesetEpilogueAbortsIf { + dr_account: signer; + txn_sequence_number: u64; + should_trigger_reconfiguration: bool; + aborts_if !exists(@DiemRoot); + include DiemTimestamp::AbortsIfNotOperating; + aborts_if signer::address_of(dr_account) != @DiemRoot with errors::INVALID_ARGUMENT; + aborts_if !Roles::has_diem_root_role(dr_account) with errors::INVALID_ARGUMENT; + include EpilogueCommonAbortsIf{account: dr_account, txn_gas_price: 0, txn_max_gas_units: 0, gas_units_remaining: 0}; + include should_trigger_reconfiguration ==> Roles::AbortsIfNotDiemRoot{account: dr_account}; + include should_trigger_reconfiguration ==> DiemConfig::ReconfigureAbortsIf; + } + spec schema WritesetEpilogueEmits { + should_trigger_reconfiguration: bool; + let handle = global(@DiemRoot).upgrade_events; + let msg = AdminTransactionEvent { + committed_timestamp_secs: DiemTimestamp::spec_now_seconds() + }; + emits msg to handle; + include should_trigger_reconfiguration ==> DiemConfig::ReconfigureEmits; + } + + /// Create a Validator account + public fun create_validator_account( + dr_account: &signer, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + ) acquires AccountOperationsCapability { + Roles::assert_diem_root(dr_account); + let new_account = create_signer(new_account_address); + // The dr_account account is verified to have the diem root role in `Roles::new_validator_role` + Roles::new_validator_role(dr_account, &new_account); + ValidatorConfig::publish(&new_account, dr_account, human_name); + make_account(&new_account, auth_key_prefix) + } + spec create_validator_account { + pragma disable_invariants_in_body; + include CreateValidatorAccountAbortsIf; + include CreateValidatorAccountEnsures; + include MakeAccountEmits; + } + spec schema CreateValidatorAccountAbortsIf { + dr_account: signer; + new_account_address: address; + // from `Roles::new_validator_role` + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include MakeAccountAbortsIf{addr: new_account_address}; + // from `ValidatorConfig::publish` + include DiemTimestamp::AbortsIfNotOperating; + aborts_if ValidatorConfig::exists_config(new_account_address) with errors::ALREADY_PUBLISHED; + } + spec schema CreateValidatorAccountEnsures { + new_account_address: address; + // Note: `Roles::GrantRole` has both ensure's and aborts_if's. + include Roles::GrantRole{addr: new_account_address, role_id: Roles::VALIDATOR_ROLE_ID}; + ensures exists_at(new_account_address); + ensures ValidatorConfig::exists_config(new_account_address); + } + + /// Create a Validator Operator account + public fun create_validator_operator_account( + dr_account: &signer, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + ) acquires AccountOperationsCapability { + Roles::assert_diem_root(dr_account); + let new_account = create_signer(new_account_address); + // The dr_account is verified to have the diem root role in `Roles::new_validator_operator_role` + Roles::new_validator_operator_role(dr_account, &new_account); + ValidatorOperatorConfig::publish(&new_account, dr_account, human_name); + make_account(&new_account, auth_key_prefix) + } + spec create_validator_operator_account { + pragma disable_invariants_in_body; + include CreateValidatorOperatorAccountAbortsIf; + include CreateValidatorOperatorAccountEnsures; + } + spec schema CreateValidatorOperatorAccountAbortsIf { + dr_account: signer; + new_account_address: address; + // from `Roles::new_validator_operator_role` + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include MakeAccountAbortsIf{addr: new_account_address}; + // from `ValidatorConfig::publish` + include DiemTimestamp::AbortsIfNotOperating; + aborts_if ValidatorOperatorConfig::has_validator_operator_config(new_account_address) with errors::ALREADY_PUBLISHED; + } + spec schema CreateValidatorOperatorAccountEnsures { + new_account_address: address; + include Roles::GrantRole{addr: new_account_address, role_id: Roles::VALIDATOR_OPERATOR_ROLE_ID}; + ensures exists_at(new_account_address); + ensures ValidatorOperatorConfig::has_validator_operator_config(new_account_address); + } + + // ****************** Module Specifications ******************* + spec module {} // switch documentation context back to module level + + /// # Access Control + + /// ## Key Rotation Capability + spec module { + /// the permission "RotateAuthenticationKey(addr)" is granted to the account at addr [[H18]][PERMISSION]. + /// When an account is created, its KeyRotationCapability is granted to the account. + apply EnsuresHasKeyRotationCap{account: new_account} to make_account; + + /// Only `make_account` creates KeyRotationCap [[H18]][PERMISSION][[I18]][PERMISSION]. `create_*_account` only calls + /// `make_account`, and does not pack KeyRotationCap by itself. + /// `restore_key_rotation_capability` restores KeyRotationCap, and does not create new one. + apply PreserveKeyRotationCapAbsence to * except make_account, create_*_account, + restore_key_rotation_capability, initialize; + + /// Every account holds either no key rotation capability (because KeyRotationCapability has been delegated) + /// or the key rotation capability for addr itself [[H18]][PERMISSION]. + invariant forall addr: address where exists_at(addr): + delegated_key_rotation_capability(addr) || spec_holds_own_key_rotation_cap(addr); + } + + spec schema EnsuresHasKeyRotationCap { + account: signer; + let addr = signer::address_of(account); + ensures spec_holds_own_key_rotation_cap(addr); + } + spec schema PreserveKeyRotationCapAbsence { + /// The absence of KeyRotationCap is preserved. + ensures forall addr: address: + old(!exists(addr) || !spec_has_key_rotation_cap(addr)) ==> + (!exists(addr) || !spec_has_key_rotation_cap(addr)); + } + + /// ## Withdraw Capability + spec module { + /// the permission "WithdrawCapability(addr)" is granted to the account at addr [[H19]][PERMISSION]. + /// When an account is created, its WithdrawCapability is granted to the account. + apply EnsuresWithdrawCap{account: new_account} to make_account; + + /// Only `make_account` creates WithdrawCap [[H19]][PERMISSION][[I19]][PERMISSION]. `create_*_account` only calls + /// `make_account`, and does not pack KeyRotationCap by itself. + /// `restore_withdraw_capability` restores WithdrawCap, and does not create new one. + apply PreserveWithdrawCapAbsence to * except make_account, create_*_account, + restore_withdraw_capability, initialize; + + /// Every account holds either no withdraw capability (because withdraw cap has been delegated) + /// or the withdraw capability for addr itself [[H19]][PERMISSION]. + invariant forall addr: address where exists_at(addr): + spec_holds_delegated_withdraw_capability(addr) || spec_holds_own_withdraw_cap(addr); + } + + spec schema EnsuresWithdrawCap { + account: signer; + let addr = signer::address_of(account); + ensures spec_holds_own_withdraw_cap(addr); + } + spec schema PreserveWithdrawCapAbsence { + /// The absence of WithdrawCap is preserved. + ensures forall addr: address: + old(!exists(addr) || option::is_none(global(addr).withdraw_capability)) ==> + (!exists(addr) || option::is_none(global(addr).withdraw_capability)); + } + + /// ## Authentication Key + + spec module { + /// only `Self::rotate_authentication_key` can rotate authentication_key [[H18]][PERMISSION]. + apply AuthenticationKeyRemainsSame to *, * except rotate_authentication_key; + } + + spec schema AuthenticationKeyRemainsSame { + ensures forall addr: address where old(exists_at(addr)): + global(addr).authentication_key == old(global(addr).authentication_key); + } + + /// ## Balance + + spec module { + /// only `Self::withdraw_from` and its helper and clients can withdraw [[H19]][PERMISSION]. + apply BalanceNotDecrease to * + except withdraw_from, withdraw_from_balance, staple_xdx, unstaple_xdx, + preburn, pay_from, pay_by_signers, epilogue_common, epilogue, failure_epilogue, success_epilogue; + } + + spec schema BalanceNotDecrease { + ensures forall addr: address where old(exists>(addr)): + global>(addr).coin.value >= old(global>(addr).coin.value); + } + + /// # Persistence of Resources + + spec module { + /// Accounts are never deleted. + invariant update forall addr: address where old(exists_at(addr)): exists_at(addr); + + /// After genesis, the `AccountOperationsCapability` exists. + invariant [suspendable] DiemTimestamp::is_operating() ==> exists(@DiemRoot); + + /// After genesis, the `DiemWriteSetManager` exists. + invariant [suspendable] DiemTimestamp::is_operating() ==> exists(@DiemRoot); + + /// resource struct `Balance` is persistent + invariant update forall addr: address + where old(exists>(addr)): + exists>(addr); + + /// resource struct `AccountOperationsCapability` is persistent + invariant update old(exists(@DiemRoot)) + ==> exists(@DiemRoot); + + /// resource struct `AccountOperationsCapability` is persistent + invariant update + old(exists(@DiemRoot)) ==> exists(@DiemRoot); + } + + /// # Other invariants + spec module { + + /// An address has a published account iff it has a published RoleId + invariant [suspendable] forall addr: address: exists_at(addr) <==> exists(addr); + + // Every address with a published account has a publish event handle generator + // >TODO: When commented in, odd things happen. + // However, this particular invariant does not need to be disabled, and the function + // needs to be public because it is a general-purpose function in stdlib. + // Also, the invariant is not specified in Events, which also seems relevant. + // invariant forall addr: address where exists_at(addr): exists(addr); + + /// There is a published AccountOperationsCapability iff there is an account and it's at Diem root address + invariant [suspendable] forall addr: address: + exists(addr) <==> (addr == @DiemRoot && exists_at(addr)); + + /// An account has a WriteSetManager iff if it is Diem root + invariant [suspendable] forall addr: address: + exists(addr) <==> (addr == @DiemRoot && exists_at(addr)); + + /// There is a VASPDomainManager at an address iff the address is a diem treasury compliance account + invariant [suspendable] forall addr: address: + exists(addr) <==> Roles::spec_has_treasury_compliance_role_addr(addr); + + /// There is a VASPDomains at an address iff the address is a Diem treasury compliance account + invariant [suspendable] forall addr: address: + exists(addr) <==> Roles::spec_has_parent_VASP_role_addr(addr); + + /// Account has a balance only iff it is parent or child VASP or a designated dealer + /// > Note: It would be better to make this generic over all existing and future coins, but that + /// would require existential quantification over types, and I'm not sure if that works with monomorphization. + // > TODO: This fails because type parameter add_currency_for_account can + // have token type that is not XDX or XUS !! + // invariant [suspendable] forall addr: address: + // (exists>(addr) || exists>(addr)) <==> Roles::spec_can_hold_balance_addr(addr); + invariant forall addr: address: + (exists>(addr) || exists>(addr)) ==> Roles::spec_can_hold_balance_addr(addr); + + /// There is a `DesignatedDealer::Dealer` published at `addr` iff the `addr` has a + /// `Roles::DesignatedDealer` role. + invariant [suspendable] forall addr: address: exists(addr) + <==> Roles::spec_has_designated_dealer_role_addr(addr); + + /// There is a DualAttestation credential iff account has designated dealer or parent VASP role + invariant [suspendable] forall addr: address: + exists(addr) + <==> (Roles::spec_has_designated_dealer_role_addr(addr) + || Roles::spec_has_parent_VASP_role_addr(addr)); + + /// An address has an account iff there is a published FreezingBit struct + invariant [suspendable] forall addr: address: + exists_at(addr) <==> exists(addr); + + // This invariant is redundant with the previous invariant, but weaker. + // But it holds throughout make_account, and is useful to prove that the + // "move_to" that publishes the account will never abort. + // TODO: This is too clever. Should modify code to an assert or requires at + // beginning of make_account that account does not already exist. + invariant [suspendable] forall addr: address: + exists_at(addr) ==> exists(addr); + + /// Balances can only be published at addresses where an account exists + /// >TODO: I think this is redundant with previous invariants. exists_at <==> Role, and + /// Balance <==> can_hold_balance + invariant [suspendable] forall addr: address where exists>(addr): + exists_at(addr); + + /// Account has SlidingNonce only if it's Diem Root or Treasury Compliance + invariant [suspendable] forall addr: address: exists(addr) + <==> (Roles::spec_has_diem_root_role_addr(addr) || Roles::spec_has_treasury_compliance_role_addr(addr)); + + /// Address has a ValidatorConfig iff it is a Validator address + invariant [suspendable] forall addr: address: ValidatorConfig::exists_config(addr) + <==> Roles::spec_has_validator_role_addr(addr); + + /// Address has a ValidatorOperatorConfig iff it is a ValidatorOperator address + invariant [suspendable] forall addr: address: ValidatorOperatorConfig::has_validator_operator_config(addr) + <==> Roles::spec_has_validator_operator_role_addr(addr); + + /// Address has a parent VASP credential iff it has a parent VASP role + invariant [suspendable] forall addr: address: VASP::is_parent(addr) + <==> Roles::spec_has_parent_VASP_role_addr(addr); + + /// Address has a child VASP credential iff it has a child VASP role + invariant [suspendable] forall addr: address: VASP::is_child(addr) + <==> Roles::spec_has_child_VASP_role_addr(addr); + } + + /// # Helper Functions and Schemas + + /// ## Capabilities + + spec module { + /// Returns field `key_rotation_capability` of the DiemAccount under `addr`. + fun spec_get_key_rotation_cap_field(addr: address): Option { + global(addr).key_rotation_capability + } + + /// Returns the KeyRotationCapability of the field `key_rotation_capability`. + fun spec_get_key_rotation_cap(addr: address): KeyRotationCapability { + option::borrow(spec_get_key_rotation_cap_field(addr)) + } + + // Returns if the account holds KeyRotationCapability. + fun spec_has_key_rotation_cap(addr: address): bool { + option::is_some(spec_get_key_rotation_cap_field(addr)) + } + + /// Returns true if the DiemAccount at `addr` holds + /// `KeyRotationCapability` for itself. + fun spec_holds_own_key_rotation_cap(addr: address): bool { + spec_has_key_rotation_cap(addr) + && addr == spec_get_key_rotation_cap(addr).account_address + } + + /// Returns true if `AccountOperationsCapability` is published. + fun spec_has_account_operations_cap(): bool { + exists(@DiemRoot) + } + + /// Returns field `withdraw_capability` of DiemAccount under `addr`. + fun spec_get_withdraw_cap_field(addr: address): Option { + global(addr).withdraw_capability + } + + /// Returns the WithdrawCapability of the field `withdraw_capability`. + fun spec_get_withdraw_cap(addr: address): WithdrawCapability { + option::borrow(spec_get_withdraw_cap_field(addr)) + } + + /// Returns true if the DiemAccount at `addr` holds a `WithdrawCapability`. + fun spec_has_withdraw_cap(addr: address): bool { + option::is_some(spec_get_withdraw_cap_field(addr)) + } + + /// Returns true if the DiemAccount at `addr` holds `WithdrawCapability` for itself. + fun spec_holds_own_withdraw_cap(addr: address): bool { + spec_has_withdraw_cap(addr) + && addr == spec_get_withdraw_cap(addr).account_address + } + + /// Returns true of the account holds a delegated withdraw capability. + fun spec_holds_delegated_withdraw_capability(addr: address): bool { + exists_at(addr) && option::is_none(global(addr).withdraw_capability) + } + + } + + /// ## Prologue + + spec fun prologue_guarantees(sender: signer) : bool { + let addr = signer::address_of(sender); + DiemTimestamp::is_operating() && exists_at(addr) && !AccountFreezing::account_is_frozen(addr) + } + + /// Used in transaction script to specify properties checked by the prologue. + spec schema TransactionChecks { + sender: signer; + requires prologue_guarantees(sender); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemBlock.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemBlock.move new file mode 100644 index 000000000..409b0a172 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemBlock.move @@ -0,0 +1,131 @@ +/// This module defines a struct storing the metadata of the block and new block events. +module DiemFramework::DiemBlock { + use DiemFramework::CoreAddresses; + use DiemFramework::DiemSystem; + use DiemFramework::DiemTimestamp; + use std::errors; + use std::event; + + struct BlockMetadata has key { + /// Height of the current block + height: u64, + /// Handle where events with the time of new blocks are emitted + new_block_events: event::EventHandle, + } + + struct NewBlockEvent has drop, store { + round: u64, + proposer: address, + previous_block_votes: vector
, + + /// On-chain time during he block at the given height + time_microseconds: u64, + } + + /// The `BlockMetadata` resource is in an invalid state + const EBLOCK_METADATA: u64 = 0; + /// An invalid signer was provided. Expected the signer to be the VM or a Validator. + const EVM_OR_VALIDATOR: u64 = 1; + + /// This can only be invoked by the Association address, and only a single time. + /// Currently, it is invoked in the genesis transaction + public fun initialize_block_metadata(account: &signer) { + DiemTimestamp::assert_genesis(); + // Operational constraint, only callable by the Association address + CoreAddresses::assert_diem_root(account); + + assert!(!is_initialized(), errors::already_published(EBLOCK_METADATA)); + move_to( + account, + BlockMetadata { + height: 0, + new_block_events: event::new_event_handle(account), + } + ); + } + spec initialize_block_metadata { + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot; + aborts_if is_initialized() with errors::ALREADY_PUBLISHED; + ensures is_initialized(); + ensures get_current_block_height() == 0; + } + + /// Helper function to determine whether this module has been initialized. + fun is_initialized(): bool { + exists(@DiemRoot) + } + + /// Set the metadata for the current block. + /// The runtime always runs this before executing the transactions in a block. + fun block_prologue( + vm: signer, + round: u64, + timestamp: u64, + previous_block_votes: vector
, + proposer: address + ) acquires BlockMetadata { + DiemTimestamp::assert_operating(); + // Operational constraint: can only be invoked by the VM. + CoreAddresses::assert_vm(&vm); + + // Authorization + assert!( + proposer == @VMReserved || DiemSystem::is_validator(proposer), + errors::requires_address(EVM_OR_VALIDATOR) + ); + + let block_metadata_ref = borrow_global_mut(@DiemRoot); + DiemTimestamp::update_global_time(&vm, proposer, timestamp); + block_metadata_ref.height = block_metadata_ref.height + 1; + event::emit_event( + &mut block_metadata_ref.new_block_events, + NewBlockEvent { + round, + proposer, + previous_block_votes, + time_microseconds: timestamp, + } + ); + } + spec block_prologue { + include DiemTimestamp::AbortsIfNotOperating; + include CoreAddresses::AbortsIfNotVM{account: vm}; + aborts_if proposer != @VMReserved && !DiemSystem::spec_is_validator(proposer) + with errors::REQUIRES_ADDRESS; + ensures DiemTimestamp::spec_now_microseconds() == timestamp; + ensures get_current_block_height() == old(get_current_block_height()) + 1; + + aborts_if get_current_block_height() + 1 > MAX_U64 with EXECUTION_FAILURE; + include BlockPrologueEmits; + } + spec schema BlockPrologueEmits { + round: u64; + timestamp: u64; + previous_block_votes: vector
; + proposer: address; + let handle = global(@DiemRoot).new_block_events; + let msg = NewBlockEvent { + round, + proposer, + previous_block_votes, + time_microseconds: timestamp, + }; + emits msg to handle; + } + + /// Get the current block height + public fun get_current_block_height(): u64 acquires BlockMetadata { + assert!(is_initialized(), errors::not_published(EBLOCK_METADATA)); + borrow_global(@DiemRoot).height + } + + spec module { } // Switch documentation context to module level. + + /// # Initialization + /// This implies that `BlockMetadata` is published after initialization and stays published + /// ever after + spec module { + invariant [suspendable] DiemTimestamp::is_operating() ==> is_initialized(); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemConfig.move new file mode 100644 index 000000000..d47c3fa85 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemConfig.move @@ -0,0 +1,472 @@ +/// Publishes configuration information for validators, and issues reconfiguration events +/// to synchronize configuration changes for the validators. +module DiemFramework::DiemConfig { + use DiemFramework::CoreAddresses; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::errors; + use std::event; + use std::signer; + friend DiemFramework::DiemVersion; + friend DiemFramework::RegisteredCurrencies; + friend DiemFramework::DiemTransactionPublishingOption; + friend DiemFramework::DiemVMConfig; + friend DiemFramework::DiemSystem; + friend DiemFramework::DiemConsensusConfig; + friend DiemFramework::ParallelExecutionConfig; + + /// A generic singleton resource that holds a value of a specific type. + struct DiemConfig has key, store { + /// Holds specific info for instance of `Config` type. + payload: Config + } + + /// Event that signals DiemBFT algorithm to start a new epoch, + /// with new configuration information. This is also called a + /// "reconfiguration event" + struct NewEpochEvent has drop, store { + epoch: u64, + } + + /// Holds information about state of reconfiguration + struct Configuration has key { + /// Epoch number + epoch: u64, + /// Time of last reconfiguration. Only changes on reconfiguration events. + last_reconfiguration_time: u64, + /// Event handle for reconfiguration events + events: event::EventHandle, + } + + /// Accounts with this privilege can modify DiemConfig under Diem root address. + struct ModifyConfigCapability has key, store {} + + /// Reconfiguration disabled if this resource occurs under LibraRoot. + struct DisableReconfiguration has key {} + + /// The `Configuration` resource is in an invalid state + const ECONFIGURATION: u64 = 0; + /// A `DiemConfig` resource is in an invalid state + const EDIEM_CONFIG: u64 = 1; + /// A `ModifyConfigCapability` is in a different state than was expected + const EMODIFY_CAPABILITY: u64 = 2; + /// An invalid block time was encountered. + const EINVALID_BLOCK_TIME: u64 = 3; + /// The largest possible u64 value + const MAX_U64: u64 = 18446744073709551615; + + /// Publishes `Configuration` resource. Can only be invoked by Diem root, and only a single time in Genesis. + public fun initialize( + dr_account: &signer, + ) { + DiemTimestamp::assert_genesis(); + CoreAddresses::assert_diem_root(dr_account); + assert!(!exists(@DiemRoot), errors::already_published(ECONFIGURATION)); + move_to( + dr_account, + Configuration { + epoch: 0, + last_reconfiguration_time: 0, + events: event::new_event_handle(dr_account), + } + ); + } + spec initialize { + pragma opaque; + include InitializeAbortsIf; + include InitializeEnsures; + modifies global(@DiemRoot); + modifies global(signer::address_of(dr_account)); + } + spec schema InitializeAbortsIf { + dr_account: signer; + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + aborts_if spec_has_config() with errors::ALREADY_PUBLISHED; + } + spec schema InitializeEnsures { + ensures spec_has_config(); + let post post_config = global(@DiemRoot); + ensures post_config.epoch == 0; + ensures post_config.last_reconfiguration_time == 0; + } + + + /// Returns a copy of `Config` value stored under `addr`. + public fun get(): Config + acquires DiemConfig { + let addr = @DiemRoot; + assert!(exists>(addr), errors::not_published(EDIEM_CONFIG)); + *&borrow_global>(addr).payload + } + spec get { + pragma opaque; + include AbortsIfNotPublished; + ensures result == get(); + } + spec schema AbortsIfNotPublished { + aborts_if !exists>(@DiemRoot) with errors::NOT_PUBLISHED; + } + + /// Set a config item to a new value with the default capability stored under config address and trigger a + /// reconfiguration. This function requires that the signer have a `ModifyConfigCapability` + /// resource published under it. + public(friend) fun set(account: &signer, payload: Config) + acquires DiemConfig, Configuration { + let signer_address = signer::address_of(account); + // Next should always be true if properly initialized. + assert!(exists>(signer_address), errors::requires_capability(EMODIFY_CAPABILITY)); + + let addr = @DiemRoot; + assert!(exists>(addr), errors::not_published(EDIEM_CONFIG)); + let config = borrow_global_mut>(addr); + config.payload = payload; + + reconfigure_(); + } + spec set { + pragma opaque; + pragma delegate_invariants_to_caller; + requires DiemTimestamp::is_operating() ==> spec_has_config(); + modifies global(@DiemRoot); + modifies global>(@DiemRoot); + include SetAbortsIf; + include SetEnsures; + } + spec schema SetAbortsIf { + account: signer; + include AbortsIfNotModifiable; + include AbortsIfNotPublished; + include ReconfigureAbortsIf; + } + spec schema AbortsIfNotModifiable { + account: signer; + aborts_if !exists>(signer::address_of(account)) + with errors::REQUIRES_CAPABILITY; + } + spec schema SetEnsures { + payload: Config; + ensures spec_is_published(); + ensures get() == payload; + ensures old(spec_has_config()) == spec_has_config(); + } + + /// Set a config item to a new value and trigger a reconfiguration. This function + /// requires a reference to a `ModifyConfigCapability`, which is returned when the + /// config is published using `publish_new_config_and_get_capability`. + /// It is called by `DiemSystem::update_config_and_reconfigure`, which allows + /// validator operators to change the validator set. All other config changes require + /// a Diem root signer. + public(friend) fun set_with_capability_and_reconfigure( + _cap: &ModifyConfigCapability, + payload: Config + ) acquires DiemConfig, Configuration { + let addr = @DiemRoot; + assert!(exists>(addr), errors::not_published(EDIEM_CONFIG)); + let config = borrow_global_mut>(addr); + config.payload = payload; + reconfigure_(); + } + spec set_with_capability_and_reconfigure { + pragma opaque; + pragma delegate_invariants_to_caller; + requires DiemTimestamp::is_operating() ==> spec_has_config(); + modifies global(@DiemRoot); + include AbortsIfNotPublished; + include ReconfigureAbortsIf; + modifies global>(@DiemRoot); + include SetEnsures; + include ReconfigureEmits; + } + + /// Private function to temporarily halt reconfiguration. + /// This function should only be used for offline WriteSet generation purpose and should never be invoked on chain. + fun disable_reconfiguration(dr_account: &signer) { + assert!( + signer::address_of(dr_account) == @DiemRoot, + errors::requires_address(EDIEM_CONFIG) + ); + Roles::assert_diem_root(dr_account); + assert!(reconfiguration_enabled(), errors::invalid_state(ECONFIGURATION)); + move_to(dr_account, DisableReconfiguration {} ) + } + + /// Private function to resume reconfiguration. + /// This function should only be used for offline WriteSet generation purpose and should never be invoked on chain. + fun enable_reconfiguration(dr_account: &signer) acquires DisableReconfiguration { + assert!( + signer::address_of(dr_account) == @DiemRoot, + errors::requires_address(EDIEM_CONFIG) + ); + Roles::assert_diem_root(dr_account); + + assert!(!reconfiguration_enabled(), errors::invalid_state(ECONFIGURATION)); + DisableReconfiguration {} = move_from(signer::address_of(dr_account)); + } + + fun reconfiguration_enabled(): bool { + !exists(@DiemRoot) + } + + /// Publishes a new config. + /// The caller will use the returned ModifyConfigCapability to specify the access control + /// policy for who can modify the config. + /// Does not trigger a reconfiguration. + public(friend) fun publish_new_config_and_get_capability( + dr_account: &signer, + payload: Config, + ): ModifyConfigCapability { + Roles::assert_diem_root(dr_account); + assert!( + !exists>(signer::address_of(dr_account)), + errors::already_published(EDIEM_CONFIG) + ); + move_to(dr_account, DiemConfig { payload }); + ModifyConfigCapability {} + } + spec publish_new_config_and_get_capability { + pragma opaque; + pragma delegate_invariants_to_caller; + modifies global>(@DiemRoot); + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include AbortsIfPublished; + include SetEnsures; + } + spec schema AbortsIfPublished { + aborts_if exists>(@DiemRoot) with errors::ALREADY_PUBLISHED; + } + + /// Publish a new config item. Only Diem root can modify such config. + /// Publishes the capability to modify this config under the Diem root account. + /// Does not trigger a reconfiguration. + public(friend) fun publish_new_config( + dr_account: &signer, + payload: Config + ) { + let capability = publish_new_config_and_get_capability(dr_account, payload); + assert!( + !exists>(signer::address_of(dr_account)), + errors::already_published(EMODIFY_CAPABILITY) + ); + move_to(dr_account, capability); + } + spec publish_new_config { + pragma opaque; + pragma delegate_invariants_to_caller; + modifies global>(@DiemRoot); + modifies global>(@DiemRoot); + include PublishNewConfigAbortsIf; + include PublishNewConfigEnsures; + } + spec schema PublishNewConfigAbortsIf { + dr_account: signer; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + aborts_if spec_is_published(); + aborts_if exists>(signer::address_of(dr_account)); + } + spec schema PublishNewConfigEnsures { + dr_account: signer; + payload: Config; + include SetEnsures; + ensures exists>(signer::address_of(dr_account)); + } + + /// Signal validators to start using new configuration. Must be called by Diem root. + public fun reconfigure( + dr_account: &signer, + ) acquires Configuration { + Roles::assert_diem_root(dr_account); + reconfigure_(); + } + spec reconfigure { + pragma opaque; + modifies global(@DiemRoot); + ensures old(spec_has_config()) == spec_has_config(); + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include ReconfigureAbortsIf; + include ReconfigureEmits; + } + + /// Private function to do reconfiguration. Updates reconfiguration status resource + /// `Configuration` and emits a `NewEpochEvent` + fun reconfigure_() acquires Configuration { + // Do not do anything if genesis has not finished. + if (DiemTimestamp::is_genesis() || DiemTimestamp::now_microseconds() == 0 || !reconfiguration_enabled()) { + return () + }; + + let config_ref = borrow_global_mut(@DiemRoot); + let current_time = DiemTimestamp::now_microseconds(); + + // Do not do anything if a reconfiguration event is already emitted within this transaction. + // + // This is OK because: + // - The time changes in every non-empty block + // - A block automatically ends after a transaction that emits a reconfiguration event, which is guaranteed by + // DiemVM spec that all transactions comming after a reconfiguration transaction will be returned as Retry + // status. + // - Each transaction must emit at most one reconfiguration event + // + // Thus, this check ensures that a transaction that does multiple "reconfiguration required" actions emits only + // one reconfiguration event. + // + if (current_time == config_ref.last_reconfiguration_time) { + return + }; + + assert!(current_time > config_ref.last_reconfiguration_time, errors::invalid_state(EINVALID_BLOCK_TIME)); + config_ref.last_reconfiguration_time = current_time; + config_ref.epoch = config_ref.epoch + 1; + + event::emit_event( + &mut config_ref.events, + NewEpochEvent { + epoch: config_ref.epoch, + }, + ); + } + spec fun spec_reconfigure_omitted(): bool { + DiemTimestamp::is_genesis() || DiemTimestamp::spec_now_microseconds() == 0 || !reconfiguration_enabled() + } + spec reconfigure_ { + pragma opaque; + modifies global(@DiemRoot); + requires DiemTimestamp::is_operating() ==> spec_has_config(); + ensures old(spec_has_config()) == spec_has_config(); + let config = global(@DiemRoot); + let post post_config = global(@DiemRoot); + let now = DiemTimestamp::spec_now_microseconds(); + let post post_now = DiemTimestamp::spec_now_microseconds(); + + include !spec_reconfigure_omitted() || (config.last_reconfiguration_time == now) + ==> InternalReconfigureAbortsIf && ReconfigureAbortsIf; + + ensures spec_reconfigure_omitted() || (config.last_reconfiguration_time == now) + ==> post_config == config; + + ensures !(spec_reconfigure_omitted() || (config.last_reconfiguration_time == now)) + ==> post_config == + update_field( + update_field(config, + epoch, config.epoch + 1), + last_reconfiguration_time, post_now); + include ReconfigureEmits; + } + /// The following schema describes aborts conditions which we do not want to be propagated to the verification + /// of callers, and which are therefore marked as `concrete` to be only verified against the implementation. + /// These conditions are unlikely to happen in reality, and excluding them avoids formal noise. + spec schema InternalReconfigureAbortsIf { + let config = global(@DiemRoot); + let current_time = DiemTimestamp::spec_now_microseconds(); + aborts_if [concrete] current_time < config.last_reconfiguration_time with errors::INVALID_STATE; + aborts_if [concrete] config.epoch == MAX_U64 + && current_time != config.last_reconfiguration_time with EXECUTION_FAILURE; + } + /// This schema is to be used by callers of `reconfigure` + spec schema ReconfigureAbortsIf { + let config = global(@DiemRoot); + let current_time = DiemTimestamp::spec_now_microseconds(); + aborts_if DiemTimestamp::is_operating() + && reconfiguration_enabled() + && DiemTimestamp::spec_now_microseconds() > 0 + && config.epoch < MAX_U64 + && current_time < config.last_reconfiguration_time + with errors::INVALID_STATE; + } + spec schema ReconfigureEmits { + let config = global(@DiemRoot); + let post post_config = global(@DiemRoot); + let post now = DiemTimestamp::spec_now_microseconds(); + let post msg = NewEpochEvent { + epoch: post_config.epoch, + }; + let handle = config.events; + emits msg to handle if (!spec_reconfigure_omitted() && now != config.last_reconfiguration_time); + } + + /// Emit a `NewEpochEvent` event. This function will be invoked by genesis directly to generate the very first + /// reconfiguration event. + fun emit_genesis_reconfiguration_event() acquires Configuration { + assert!(exists(@DiemRoot), errors::not_published(ECONFIGURATION)); + let config_ref = borrow_global_mut(@DiemRoot); + assert!(config_ref.epoch == 0 && config_ref.last_reconfiguration_time == 0, errors::invalid_state(ECONFIGURATION)); + config_ref.epoch = 1; + + event::emit_event( + &mut config_ref.events, + NewEpochEvent { + epoch: config_ref.epoch, + }, + ); + } + spec emit_genesis_reconfiguration_event { + let post config = global(@DiemRoot); + let post handle = config.events; + let post msg = NewEpochEvent { + epoch: config.epoch, + }; + ensures config.epoch == 1; + emits msg to handle; + } + + // ================================================================= + // Test-only functions + + #[test_only] + public fun set_for_testing(account: &signer, payload: Config) + acquires DiemConfig, Configuration { + set(account, payload) + } + + #[test_only] + public fun publish_new_config_for_testing( + dr_account: &signer, + payload: Config + ) { + publish_new_config(dr_account, payload); + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Initialization + spec module { + /// After genesis, the `Configuration` is published. + invariant [suspendable] DiemTimestamp::is_operating() ==> spec_has_config(); + } + + /// # Invariants + spec module { + /// Configurations are only stored at the diem root address. + invariant + forall config_address: address where exists>(config_address): + config_address == @DiemRoot; + + /// Published configurations are persistent. + invariant update + old(spec_is_published()) ==> spec_is_published(); + + /// If `ModifyConfigCapability` is published, it is persistent. + invariant update + old(exists>(@DiemRoot)) ==> + exists>(@DiemRoot); + } + + /// # Helper Functions + spec module { + fun spec_has_config(): bool { + exists(@DiemRoot) + } + + fun spec_is_published(): bool { + exists>(@DiemRoot) + } + + fun spec_get_config(): Config { + global>(@DiemRoot).payload + } + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemConsensusConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemConsensusConfig.move new file mode 100644 index 000000000..4c7e8220f --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemConsensusConfig.move @@ -0,0 +1,72 @@ +/// Maintains the consensus config for the Diem blockchain. The config is stored in a +/// DiemConfig, and may be updated by Diem root. +module DiemFramework::DiemConsensusConfig { + use DiemFramework::DiemConfig::{Self, DiemConfig}; + use DiemFramework::Roles; + use std::vector; + + struct DiemConsensusConfig has copy, drop, store { + config: vector, + } + + /// Publishes the DiemConsensusConfig config. + public fun initialize(dr_account: &signer) { + Roles::assert_diem_root(dr_account); + DiemConfig::publish_new_config(dr_account, DiemConsensusConfig { config: vector::empty() }); + } + spec initialize { + /// Must abort if the signer does not have the DiemRoot role [[H12]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemConfig::PublishNewConfigAbortsIf; + include DiemConfig::PublishNewConfigEnsures{ + payload: DiemConsensusConfig { config: vector::empty() } + }; + } + + /// Allows Diem root to update the config. + public fun set(dr_account: &signer, config: vector) { + Roles::assert_diem_root(dr_account); + + DiemConfig::set( + dr_account, + DiemConsensusConfig { config } + ); + } + spec set { + /// Must abort if the signer does not have the DiemRoot role [[H12]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemConfig::SetAbortsIf{account: dr_account}; + include DiemConfig::SetEnsures{payload: DiemConsensusConfig { config }}; + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Access Control + + /// The permission "UpdateDiemConsensusConfig" is granted to DiemRoot [[H12]][PERMISSION]. + spec module { + invariant [suspendable] forall addr: address + where exists>(addr): addr == @DiemRoot; + + invariant update [suspendable] old(DiemConfig::spec_is_published()) + && DiemConfig::spec_is_published() + && old(DiemConfig::get()) != DiemConfig::get() + ==> Roles::spec_signed_by_diem_root_role(); + } + + // TODO: The following is the old style spec, which can removed later. + /// Only "set" can modify the DiemConsensusConfig config [[H12]][PERMISSION] + spec schema DiemConsensusConfigRemainsSame { + ensures old(DiemConfig::spec_is_published()) ==> + global>(@DiemRoot) == + old(global>(@DiemRoot)); + } + spec module { + apply DiemConsensusConfigRemainsSame to * except set; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemId.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemId.move new file mode 100644 index 000000000..fdc3f772e --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemId.move @@ -0,0 +1,303 @@ +/// Module managing Diem ID. +module DiemFramework::DiemId { + use std::event::{Self, EventHandle}; + use DiemFramework::Roles; + use std::errors; + use std::signer; + use std::vector; + + /// This resource holds an entity's domain names needed to send and receive payments using diem IDs. + struct DiemIdDomains has key { + /// The list of domain names owned by this parent vasp account + domains: vector, + } + spec DiemIdDomains { + /// All `DiemIdDomain`s stored in the `DiemIdDomains` resource are no more than 63 characters long. + invariant forall i in 0..len(domains): len(domains[i].domain) <= DOMAIN_LENGTH; + /// The list of `DiemIdDomain`s are a set + invariant forall i in 0..len(domains): + forall j in i + 1..len(domains): domains[i] != domains[j]; + } + + /// Struct to store the limit on-chain + struct DiemIdDomain has drop, store, copy { + domain: vector, // UTF-8 encoded and 63 characters + } + spec DiemIdDomain { + /// All `DiemIdDomain`s must be no more than 63 characters long. + invariant len(domain) <= DOMAIN_LENGTH; + } + + struct DiemIdDomainManager has key { + /// Event handle for `domains` added or removed events. Emitted every time a domain is added + /// or removed to `domains` + diem_id_domain_events: EventHandle, + } + + struct DiemIdDomainEvent has drop, store { + /// Whether a domain was added or removed + removed: bool, + /// Diem ID Domain string of the account + domain: DiemIdDomain, + /// On-chain account address + address: address, + } + + const DOMAIN_LENGTH: u64 = 63; + + // Error codes + /// DiemIdDomains resource is not or already published. + const EDIEM_ID_DOMAIN: u64 = 0; + /// DiemIdDomainManager resource is not or already published. + const EDIEM_ID_DOMAIN_MANAGER: u64 = 1; + /// DiemID domain was not found + const EDOMAIN_NOT_FOUND: u64 = 2; + /// DiemID domain already exists + const EDOMAIN_ALREADY_EXISTS: u64 = 3; + /// DiemIdDomains resource was not published for a VASP account + const EDIEM_ID_DOMAINS_NOT_PUBLISHED: u64 = 4; + /// Invalid domain for DiemIdDomain + const EINVALID_DIEM_ID_DOMAIN: u64 = 5; + + fun create_diem_id_domain(domain: vector): DiemIdDomain { + assert!(vector::length(&domain) <= DOMAIN_LENGTH, errors::invalid_argument(EINVALID_DIEM_ID_DOMAIN)); + DiemIdDomain{ domain } + } + spec create_diem_id_domain { + include CreateDiemIdDomainAbortsIf; + ensures result == DiemIdDomain { domain }; + } + spec schema CreateDiemIdDomainAbortsIf { + domain: vector; + aborts_if vector::length(domain) > DOMAIN_LENGTH with errors::INVALID_ARGUMENT; + } + + /// Publish a `DiemIdDomains` resource under `created` with an empty `domains`. + /// Before sending or receiving any payments using Diem IDs, the Treasury Compliance account must send + /// a transaction that invokes `add_domain_id` to set the `domains` field with a valid domain + public fun publish_diem_id_domains( + vasp_account: &signer, + ) { + Roles::assert_parent_vasp_role(vasp_account); + assert!( + !exists(signer::address_of(vasp_account)), + errors::already_published(EDIEM_ID_DOMAIN) + ); + move_to(vasp_account, DiemIdDomains { + domains: vector::empty(), + }) + } + spec publish_diem_id_domains { + let vasp_addr = signer::address_of(vasp_account); + include Roles::AbortsIfNotParentVasp{account: vasp_account}; + include PublishDiemIdDomainsAbortsIf; + include PublishDiemIdDomainsEnsures; + } + spec schema PublishDiemIdDomainsAbortsIf { + vasp_addr: address; + aborts_if has_diem_id_domains(vasp_addr) with errors::ALREADY_PUBLISHED; + } + spec schema PublishDiemIdDomainsEnsures { + vasp_addr: address; + ensures exists(vasp_addr); + ensures vector::is_empty(global(vasp_addr).domains); + } + + public fun has_diem_id_domains(addr: address): bool { + exists(addr) + } + spec has_diem_id_domains { + aborts_if false; + ensures result == exists(addr); + } + + /// Publish a `DiemIdDomainManager` resource under `tc_account` with an empty `diem_id_domain_events`. + /// When Treasury Compliance account sends a transaction that invokes either `add_diem_id_domain` or + /// `remove_diem_id_domain`, a `DiemIdDomainEvent` is emitted and added to `diem_id_domain_events`. + public fun publish_diem_id_domain_manager( + tc_account : &signer, + ) { + Roles::assert_treasury_compliance(tc_account); + assert!( + !exists(signer::address_of(tc_account)), + errors::already_published(EDIEM_ID_DOMAIN_MANAGER) + ); + move_to( + tc_account, + DiemIdDomainManager { + diem_id_domain_events: event::new_event_handle(tc_account), + } + ); + } + spec publish_diem_id_domain_manager { + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + aborts_if tc_domain_manager_exists() with errors::ALREADY_PUBLISHED; + ensures exists(signer::address_of(tc_account)); + modifies global(signer::address_of(tc_account)); + } + + /// Add a DiemIdDomain to a parent VASP's DiemIdDomains resource. + /// When updating DiemIdDomains, a simple duplicate domain check is done. + /// However, since domains are case insensitive, it is possible by error that two same domains in + /// different lowercase and uppercase format gets added. + public fun add_diem_id_domain( + tc_account: &signer, + address: address, + domain: vector, + ) acquires DiemIdDomainManager, DiemIdDomains { + Roles::assert_treasury_compliance(tc_account); + assert!(tc_domain_manager_exists(), errors::not_published(EDIEM_ID_DOMAIN_MANAGER)); + assert!( + exists(address), + errors::not_published(EDIEM_ID_DOMAINS_NOT_PUBLISHED) + ); + + let account_domains = borrow_global_mut(address); + let diem_id_domain = create_diem_id_domain(domain); + + assert!( + !vector::contains(&account_domains.domains, &diem_id_domain), + errors::invalid_argument(EDOMAIN_ALREADY_EXISTS) + ); + + vector::push_back(&mut account_domains.domains, copy diem_id_domain); + + event::emit_event( + &mut borrow_global_mut(@TreasuryCompliance).diem_id_domain_events, + DiemIdDomainEvent { + removed: false, + domain: diem_id_domain, + address, + }, + ); + } + spec add_diem_id_domain { + include AddDiemIdDomainAbortsIf; + include AddDiemIdDomainEnsures; + include AddDiemIdDomainEmits; + } + spec schema AddDiemIdDomainAbortsIf { + tc_account: signer; + address: address; + domain: vector; + let domains = global(address).domains; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include CreateDiemIdDomainAbortsIf; + aborts_if !exists(address) with errors::NOT_PUBLISHED; + aborts_if !tc_domain_manager_exists() with errors::NOT_PUBLISHED; + aborts_if contains(domains, DiemIdDomain { domain }) with errors::INVALID_ARGUMENT; + } + spec schema AddDiemIdDomainEnsures { + address: address; + domain: vector; + let post domains = global(address).domains; + ensures contains(domains, DiemIdDomain { domain }); + } + spec schema AddDiemIdDomainEmits { + address: address; + domain: vector; + let handle = global(@TreasuryCompliance).diem_id_domain_events; + let msg = DiemIdDomainEvent { + removed: false, + domain: DiemIdDomain { domain }, + address, + }; + emits msg to handle; + } + + /// Remove a DiemIdDomain from a parent VASP's DiemIdDomains resource. + public fun remove_diem_id_domain( + tc_account: &signer, + address: address, + domain: vector, + ) acquires DiemIdDomainManager, DiemIdDomains { + Roles::assert_treasury_compliance(tc_account); + assert!(tc_domain_manager_exists(), errors::not_published(EDIEM_ID_DOMAIN_MANAGER)); + assert!( + exists(address), + errors::not_published(EDIEM_ID_DOMAINS_NOT_PUBLISHED) + ); + + let account_domains = borrow_global_mut(address); + let diem_id_domain = create_diem_id_domain(domain); + + let (has, index) = vector::index_of(&account_domains.domains, &diem_id_domain); + if (has) { + vector::remove(&mut account_domains.domains, index); + } else { + abort errors::invalid_argument(EDOMAIN_NOT_FOUND) + }; + + event::emit_event( + &mut borrow_global_mut(@TreasuryCompliance).diem_id_domain_events, + DiemIdDomainEvent { + removed: true, + domain: diem_id_domain, + address: address, + }, + ); + } + spec remove_diem_id_domain { + include RemoveDiemIdDomainAbortsIf; + include RemoveDiemIdDomainEnsures; + include RemoveDiemIdDomainEmits; + } + spec schema RemoveDiemIdDomainAbortsIf { + tc_account: signer; + address: address; + domain: vector; + let domains = global(address).domains; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include CreateDiemIdDomainAbortsIf; + aborts_if !exists(address) with errors::NOT_PUBLISHED; + aborts_if !tc_domain_manager_exists() with errors::NOT_PUBLISHED; + aborts_if !contains(domains, DiemIdDomain { domain }) with errors::INVALID_ARGUMENT; + } + spec schema RemoveDiemIdDomainEnsures { + address: address; + domain: vector; + let post domains = global(address).domains; + ensures !contains(domains, DiemIdDomain { domain }); + } + spec schema RemoveDiemIdDomainEmits { + tc_account: signer; + address: address; + domain: vector; + let handle = global(@TreasuryCompliance).diem_id_domain_events; + let msg = DiemIdDomainEvent { + removed: true, + domain: DiemIdDomain { domain }, + address, + }; + emits msg to handle; + } + + public fun has_diem_id_domain(addr: address, domain: vector): bool acquires DiemIdDomains { + assert!( + exists(addr), + errors::not_published(EDIEM_ID_DOMAINS_NOT_PUBLISHED) + ); + let account_domains = borrow_global(addr); + let diem_id_domain = create_diem_id_domain(domain); + vector::contains(&account_domains.domains, &diem_id_domain) + } + spec has_diem_id_domain { + include HasDiemIdDomainAbortsIf; + let id_domain = DiemIdDomain { domain }; + ensures result == contains(global(addr).domains, id_domain); + } + spec schema HasDiemIdDomainAbortsIf { + addr: address; + domain: vector; + include CreateDiemIdDomainAbortsIf; + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + } + + public fun tc_domain_manager_exists(): bool { + exists(@TreasuryCompliance) + } + spec tc_domain_manager_exists { + aborts_if false; + ensures result == exists(@TreasuryCompliance); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemSystem.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemSystem.move new file mode 100644 index 000000000..4a16fccce --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemSystem.move @@ -0,0 +1,685 @@ +/// Maintains information about the set of validators used during consensus. +/// Provides functions to add, remove, and update validators in the +/// validator set. +/// +/// > Note: When trying to understand this code, it's important to know that "config" +/// and "configuration" are used for several distinct concepts. +module DiemFramework::DiemSystem { + use DiemFramework::DiemConfig::{Self, DiemConfig, ModifyConfigCapability}; + use DiemFramework::ValidatorConfig; + use DiemFramework::Roles; + use DiemFramework::DiemTimestamp; + use std::errors; + use std::option::{Self, Option}; + use std::signer; + use std::vector; + + /// Information about a Validator Owner. + struct ValidatorInfo has copy, drop, store { + /// The address (account) of the Validator Owner + addr: address, + /// The voting power of the Validator Owner (currently always 1). + consensus_voting_power: u64, + /// Configuration information about the Validator, such as the + /// Validator Operator, human name, and info such as consensus key + /// and network addresses. + config: ValidatorConfig::Config, + /// The time of last reconfiguration invoked by this validator + /// in microseconds + last_config_update_time: u64, + } + + /// Enables a scheme that restricts the DiemSystem config + /// in DiemConfig from being modified by any other module. Only + /// code in this module can get a reference to the ModifyConfigCapability, + /// which is required by `DiemConfig::set_with_capability_and_reconfigure` to + /// modify the DiemSystem config. This is only needed by `update_config_and_reconfigure`. + /// Only Diem root can add or remove a validator from the validator set, so the + /// capability is not needed for access control in those functions. + struct CapabilityHolder has key { + /// Holds a capability returned by `DiemConfig::publish_new_config_and_get_capability` + /// which is called in `initialize_validator_set`. + cap: ModifyConfigCapability, + } + + /// The DiemSystem struct stores the validator set and crypto scheme in + /// DiemConfig. The DiemSystem struct is stored by DiemConfig, which publishes a + /// DiemConfig resource. + struct DiemSystem has copy, drop, store { + /// The current consensus crypto scheme. + scheme: u8, + /// The current validator set. + validators: vector, + } + spec DiemSystem { + /// Members of `validators` vector (the validator set) have unique addresses. + invariant + forall i in 0..len(validators), j in 0..len(validators): + validators[i].addr == validators[j].addr ==> i == j; + } + + /// The `CapabilityHolder` resource was not in the required state + const ECAPABILITY_HOLDER: u64 = 0; + /// Tried to add a validator with an invalid state to the validator set + const EINVALID_PROSPECTIVE_VALIDATOR: u64 = 1; + /// Tried to add a validator to the validator set that was already in it + const EALREADY_A_VALIDATOR: u64 = 2; + /// An operation was attempted on an address not in the vaidator set + const ENOT_AN_ACTIVE_VALIDATOR: u64 = 3; + /// The validator operator is not the operator for the specified validator + const EINVALID_TRANSACTION_SENDER: u64 = 4; + /// An out of bounds index for the validator set was encountered + const EVALIDATOR_INDEX: u64 = 5; + /// Rate limited when trying to update config + const ECONFIG_UPDATE_RATE_LIMITED: u64 = 6; + /// Validator set already at maximum allowed size + const EMAX_VALIDATORS: u64 = 7; + /// Validator config update time overflows + const ECONFIG_UPDATE_TIME_OVERFLOWS: u64 = 8; + + /// Number of microseconds in 5 minutes + const FIVE_MINUTES: u64 = 300000000; + + /// The maximum number of allowed validators in the validator set + const MAX_VALIDATORS: u64 = 256; + + /// The largest possible u64 value + const MAX_U64: u64 = 18446744073709551615; + + /////////////////////////////////////////////////////////////////////////// + // Setup methods + /////////////////////////////////////////////////////////////////////////// + + + /// Publishes the DiemConfig for the DiemSystem struct, which contains the current + /// validator set. Also publishes the `CapabilityHolder` with the + /// ModifyConfigCapability returned by the publish function, which allows + /// code in this module to change DiemSystem config (including the validator set). + /// Must be invoked by the Diem root a single time in Genesis. + public fun initialize_validator_set( + dr_account: &signer, + ) { + DiemTimestamp::assert_genesis(); + Roles::assert_diem_root(dr_account); + + let cap = DiemConfig::publish_new_config_and_get_capability( + dr_account, + DiemSystem { + scheme: 0, + validators: vector::empty(), + }, + ); + assert!( + !exists(@DiemRoot), + errors::already_published(ECAPABILITY_HOLDER) + ); + move_to(dr_account, CapabilityHolder { cap }) + } + spec initialize_validator_set { + modifies global>(@DiemRoot); + include DiemTimestamp::AbortsIfNotGenesis; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + let dr_addr = signer::address_of(dr_account); + // TODO: The next two aborts_if's are not independent. Perhaps they can be + // simplified. + aborts_if DiemConfig::spec_is_published() with errors::ALREADY_PUBLISHED; + aborts_if exists(dr_addr) with errors::ALREADY_PUBLISHED; + ensures exists(dr_addr); + ensures DiemConfig::spec_is_published(); + ensures len(spec_get_validators()) == 0; + ensures DiemConfig::get().scheme == 0; + } + + /// Copies a DiemSystem struct into the DiemConfig resource + /// Called by the add, remove, and update functions. + fun set_diem_system_config(value: DiemSystem) acquires CapabilityHolder { + DiemTimestamp::assert_operating(); + assert!( + exists(@DiemRoot), + errors::not_published(ECAPABILITY_HOLDER) + ); + // Updates the DiemConfig and emits a reconfigure event. + DiemConfig::set_with_capability_and_reconfigure( + &borrow_global(@DiemRoot).cap, + value + ) + } + spec set_diem_system_config { + pragma opaque; + pragma delegate_invariants_to_caller; + requires DiemTimestamp::is_operating() ==> ( + DiemConfig::spec_has_config() && + DiemConfig::spec_is_published() && + exists(@DiemRoot) + ); + modifies global>(@DiemRoot); + modifies global(@DiemRoot); + include DiemTimestamp::AbortsIfNotOperating; + include DiemConfig::ReconfigureAbortsIf; + /// `payload` is the only field of DiemConfig, so next completely specifies it. + ensures global>(@DiemRoot).payload == value; + include DiemConfig::SetEnsures{payload: value}; + include DiemConfig::ReconfigureEmits; + } + + /////////////////////////////////////////////////////////////////////////// + // Methods operating the Validator Set config callable by the diem root account + /////////////////////////////////////////////////////////////////////////// + + /// Adds a new validator to the validator set. + public fun add_validator( + dr_account: &signer, + validator_addr: address + ) acquires CapabilityHolder { + DiemTimestamp::assert_operating(); + Roles::assert_diem_root(dr_account); + + // A prospective validator must have a validator config resource + assert!( + ValidatorConfig::is_valid(validator_addr), + errors::invalid_argument(EINVALID_PROSPECTIVE_VALIDATOR) + ); + + // Bound the validator set size + assert!( + validator_set_size() < MAX_VALIDATORS, + errors::limit_exceeded(EMAX_VALIDATORS) + ); + + let diem_system_config = get_diem_system_config(); + + // Ensure that this address is not already a validator + assert!( + !is_validator_(validator_addr, &diem_system_config.validators), + errors::invalid_argument(EALREADY_A_VALIDATOR) + ); + + // it is guaranteed that the config is non-empty + let config = ValidatorConfig::get_config(validator_addr); + vector::push_back(&mut diem_system_config.validators, ValidatorInfo { + addr: validator_addr, + config, // copy the config over to ValidatorSet + consensus_voting_power: 1, + last_config_update_time: DiemTimestamp::now_microseconds(), + }); + + set_diem_system_config(diem_system_config); + } + spec add_validator { + modifies global>(@DiemRoot); + include AddValidatorAbortsIf; + include AddValidatorEnsures; + include DiemConfig::ReconfigureEmits; + } + spec schema AddValidatorAbortsIf { + dr_account: signer; + validator_addr: address; + aborts_if validator_set_size() >= MAX_VALIDATORS with errors::LIMIT_EXCEEDED; + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include DiemConfig::ReconfigureAbortsIf; + aborts_if !ValidatorConfig::is_valid(validator_addr) with errors::INVALID_ARGUMENT; + aborts_if spec_is_validator(validator_addr) with errors::INVALID_ARGUMENT; + } + spec schema AddValidatorEnsures { + validator_addr: address; + /// DIP-6 property: validator has validator role. The code does not check this explicitly, + /// but it is implied by the `assert ValidatorConfig::is_valid`, since there + /// is an invariant (in ValidatorConfig) that a an address with a published ValidatorConfig has + /// a ValidatorRole + ensures Roles::spec_has_validator_role_addr(validator_addr); + ensures ValidatorConfig::is_valid(validator_addr); + ensures spec_is_validator(validator_addr); + let vs = spec_get_validators(); + let post post_vs = spec_get_validators(); + ensures vector::eq_push_back(post_vs, + vs, + ValidatorInfo { + addr: validator_addr, + config: ValidatorConfig::spec_get_config(validator_addr), + consensus_voting_power: 1, + last_config_update_time: DiemTimestamp::spec_now_microseconds(), + } + ); + } + + + /// Removes a validator, aborts unless called by diem root account + public fun remove_validator( + dr_account: &signer, + validator_addr: address + ) acquires CapabilityHolder { + DiemTimestamp::assert_operating(); + Roles::assert_diem_root(dr_account); + let diem_system_config = get_diem_system_config(); + // Ensure that this address is an active validator + let to_remove_index_vec = get_validator_index_(&diem_system_config.validators, validator_addr); + assert!(option::is_some(&to_remove_index_vec), errors::invalid_argument(ENOT_AN_ACTIVE_VALIDATOR)); + let to_remove_index = *option::borrow(&to_remove_index_vec); + // Remove corresponding ValidatorInfo from the validator set + _ = vector::swap_remove(&mut diem_system_config.validators, to_remove_index); + + set_diem_system_config(diem_system_config); + } + spec remove_validator { + modifies global>(@DiemRoot); + include RemoveValidatorAbortsIf; + include RemoveValidatorEnsures; + include DiemConfig::ReconfigureEmits; + } + spec schema RemoveValidatorAbortsIf { + dr_account: signer; + validator_addr: address; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include DiemTimestamp::AbortsIfNotOperating; + include DiemConfig::ReconfigureAbortsIf; + aborts_if !spec_is_validator(validator_addr) with errors::INVALID_ARGUMENT; + } + spec schema RemoveValidatorEnsures { + validator_addr: address; + let vs = spec_get_validators(); + let post post_vs = spec_get_validators(); + ensures forall vi in post_vs where vi.addr != validator_addr: exists ovi in vs: vi == ovi; + /// Removed validator is no longer a validator. Depends on no other entries for same address + /// in validator_set + ensures !spec_is_validator(validator_addr); + } + + /// Copy the information from ValidatorConfig into the validator set. + /// This function makes no changes to the size or the members of the set. + /// If the config in the ValidatorSet changes, it stores the new DiemSystem + /// and emits a reconfigurationevent. + public fun update_config_and_reconfigure( + validator_operator_account: &signer, + validator_addr: address, + ) acquires CapabilityHolder { + DiemTimestamp::assert_operating(); + Roles::assert_validator_operator(validator_operator_account); + assert!( + ValidatorConfig::get_operator(validator_addr) == signer::address_of(validator_operator_account), + errors::invalid_argument(EINVALID_TRANSACTION_SENDER) + ); + let diem_system_config = get_diem_system_config(); + let to_update_index_vec = get_validator_index_(&diem_system_config.validators, validator_addr); + assert!(option::is_some(&to_update_index_vec), errors::invalid_argument(ENOT_AN_ACTIVE_VALIDATOR)); + let to_update_index = *option::borrow(&to_update_index_vec); + let is_validator_info_updated = update_ith_validator_info_(&mut diem_system_config.validators, to_update_index); + if (is_validator_info_updated) { + let validator_info = vector::borrow_mut(&mut diem_system_config.validators, to_update_index); + assert!( + validator_info.last_config_update_time <= MAX_U64 - FIVE_MINUTES, + errors::limit_exceeded(ECONFIG_UPDATE_TIME_OVERFLOWS) + ); + assert!( + DiemTimestamp::now_microseconds() > validator_info.last_config_update_time + FIVE_MINUTES, + errors::limit_exceeded(ECONFIG_UPDATE_RATE_LIMITED) + ); + validator_info.last_config_update_time = DiemTimestamp::now_microseconds(); + set_diem_system_config(diem_system_config); + } + } + spec update_config_and_reconfigure { + pragma opaque; + modifies global(@DiemRoot); + modifies global>(@DiemRoot); + include ValidatorConfig::AbortsIfGetOperator{addr: validator_addr}; + include UpdateConfigAndReconfigureAbortsIf; + include UpdateConfigAndReconfigureEnsures; + // The property below is not in `UpdateConfigAndReconfigureEnsures` because that is reused + // with a different condition in the transaction script `set_validator_config_and_reconfigure`. + // The validator set is not updated if: (1) `validator_addr` is not in the validator set, or + // (2) the validator info would not change. The code only does a reconfiguration if the + // validator set would change. `ReconfigureAbortsIf` complains if the block time does not + // advance, but block time only advances if there is a reconfiguration. + let is_validator_info_updated = + ValidatorConfig::is_valid(validator_addr) && + (exists v_info in spec_get_validators(): + v_info.addr == validator_addr + && v_info.config != ValidatorConfig::spec_get_config(validator_addr)); + include is_validator_info_updated ==> DiemConfig::ReconfigureAbortsIf; + let validator_index = + spec_index_of_validator(spec_get_validators(), validator_addr); + let last_config_time = spec_get_validators()[validator_index].last_config_update_time; + aborts_if is_validator_info_updated && last_config_time > MAX_U64 - FIVE_MINUTES + with errors::LIMIT_EXCEEDED; + aborts_if is_validator_info_updated && DiemTimestamp::spec_now_microseconds() <= last_config_time + FIVE_MINUTES + with errors::LIMIT_EXCEEDED; + include UpdateConfigAndReconfigureEmits; + } + spec schema UpdateConfigAndReconfigureAbortsIf { + validator_addr: address; + validator_operator_account: signer; + let validator_operator_addr = signer::address_of(validator_operator_account); + include DiemTimestamp::AbortsIfNotOperating; + /// Must abort if the signer does not have the ValidatorOperator role [[H15]][PERMISSION]. + include Roles::AbortsIfNotValidatorOperator{account: validator_operator_account}; + include ValidatorConfig::AbortsIfNoValidatorConfig{addr: validator_addr}; + aborts_if ValidatorConfig::get_operator(validator_addr) != validator_operator_addr + with errors::INVALID_ARGUMENT; + aborts_if !spec_is_validator(validator_addr) with errors::INVALID_ARGUMENT; + } + /// Does not change the length of the validator set, only changes ValidatorInfo + /// for validator_addr, and doesn't change any addresses. + spec schema UpdateConfigAndReconfigureEnsures { + validator_addr: address; + let vs = spec_get_validators(); + let post post_vs = spec_get_validators(); + ensures len(post_vs) == len(vs); + /// No addresses change in the validator set + ensures forall i in 0..len(vs): post_vs[i].addr == vs[i].addr; + /// If the `ValidatorInfo` address is not the one we're changing, the info does not change. + ensures forall i in 0..len(vs) where vs[i].addr != validator_addr: + post_vs[i] == vs[i]; + /// It updates the correct entry in the correct way + ensures forall i in 0..len(vs): post_vs[i].config == vs[i].config || + (vs[i].addr == validator_addr && + post_vs[i].config == ValidatorConfig::get_config(validator_addr)); + /// DIP-6 property + ensures Roles::spec_has_validator_role_addr(validator_addr); + } + spec schema UpdateConfigAndReconfigureEmits { + validator_addr: address; + let is_validator_info_updated = + ValidatorConfig::is_valid(validator_addr) && + (exists v_info in spec_get_validators(): + v_info.addr == validator_addr + && v_info.config != ValidatorConfig::spec_get_config(validator_addr)); + include is_validator_info_updated ==> DiemConfig::ReconfigureEmits; + } + + /////////////////////////////////////////////////////////////////////////// + // Publicly callable APIs: getters + /////////////////////////////////////////////////////////////////////////// + + /// Get the DiemSystem configuration from DiemConfig + public fun get_diem_system_config(): DiemSystem { + DiemConfig::get() + } + spec get_diem_system_config { + pragma opaque; + include DiemConfig::AbortsIfNotPublished; + ensures result == DiemConfig::get(); + } + + /// Return true if `addr` is in the current validator set + public fun is_validator(addr: address): bool { + is_validator_(addr, &get_diem_system_config().validators) + } + spec is_validator { + pragma opaque; + // TODO: Publication of DiemConfig in initialization + // and persistence of configs implies that the next abort cannot + // actually happen. + include DiemConfig::AbortsIfNotPublished; + ensures result == spec_is_validator(addr); + } + spec fun spec_is_validator(addr: address): bool { + exists v in spec_get_validators(): v.addr == addr + } + + /// Returns validator config. Aborts if `addr` is not in the validator set. + public fun get_validator_config(addr: address): ValidatorConfig::Config { + let diem_system_config = get_diem_system_config(); + let validator_index_vec = get_validator_index_(&diem_system_config.validators, addr); + assert!(option::is_some(&validator_index_vec), errors::invalid_argument(ENOT_AN_ACTIVE_VALIDATOR)); + *&(vector::borrow(&diem_system_config.validators, *option::borrow(&validator_index_vec))).config + } + spec get_validator_config { + pragma opaque; + include DiemConfig::AbortsIfNotPublished; + aborts_if !spec_is_validator(addr) with errors::INVALID_ARGUMENT; + ensures + exists info in DiemConfig::get().validators where info.addr == addr: + result == info.config; + } + + /// Return the size of the current validator set + public fun validator_set_size(): u64 { + vector::length(&get_diem_system_config().validators) + } + spec validator_set_size { + pragma opaque; + include DiemConfig::AbortsIfNotPublished; + ensures result == len(spec_get_validators()); + } + + /// Get the `i`'th validator address in the validator set. + public fun get_ith_validator_address(i: u64): address { + assert!(i < validator_set_size(), errors::invalid_argument(EVALIDATOR_INDEX)); + vector::borrow(&get_diem_system_config().validators, i).addr + } + spec get_ith_validator_address { + pragma opaque; + include DiemConfig::AbortsIfNotPublished; + aborts_if i >= len(spec_get_validators()) with errors::INVALID_ARGUMENT; + ensures result == spec_get_validators()[i].addr; + } + + /////////////////////////////////////////////////////////////////////////// + // Private functions + /////////////////////////////////////////////////////////////////////////// + + /// Get the index of the validator by address in the `validators` vector + /// It has a loop, so there are spec blocks in the code to assert loop invariants. + fun get_validator_index_(validators: &vector, addr: address): Option { + let size = vector::length(validators); + let i = 0; + while ({ + spec { + invariant i <= size; + invariant forall j in 0..i: validators[j].addr != addr; + }; + (i < size) + }) + { + let validator_info_ref = vector::borrow(validators, i); + if (validator_info_ref.addr == addr) { + spec { + assert validators[i].addr == addr; + }; + return option::some(i) + }; + i = i + 1; + }; + spec { + assert i == size; + assert forall j in 0..size: validators[j].addr != addr; + }; + return option::none() + } + spec get_validator_index_ { + pragma opaque; + aborts_if false; + let size = len(validators); + /// If `addr` is not in validator set, returns none. + ensures (forall i in 0..size: validators[i].addr != addr) ==> option::is_none(result); + /// If `addr` is in validator set, return the least index of an entry with that address. + /// The data invariant associated with the DiemSystem.validators that implies + /// that there is exactly one such address. + ensures + (exists i in 0..size: validators[i].addr == addr) ==> + option::is_some(result) + && { + let at = option::borrow(result); + at == spec_index_of_validator(validators, addr) + }; + } + + /// Updates *i*th validator info, if nothing changed, return false. + /// This function never aborts. + fun update_ith_validator_info_(validators: &mut vector, i: u64): bool { + let size = vector::length(validators); + // This provably cannot happen, but left it here for safety. + if (i >= size) { + return false + }; + let validator_info = vector::borrow_mut(validators, i); + // "is_valid" below should always hold based on a global invariant later + // in the file (which proves if we comment out some other specifications), + // but it is left here for safety. + if (!ValidatorConfig::is_valid(validator_info.addr)) { + return false + }; + let new_validator_config = ValidatorConfig::get_config(validator_info.addr); + // check if information is the same + let config_ref = &mut validator_info.config; + if (config_ref == &new_validator_config) { + return false + }; + *config_ref = new_validator_config; + true + } + spec update_ith_validator_info_ { + pragma opaque; + aborts_if false; + let new_validator_config = ValidatorConfig::spec_get_config(validators[i].addr); + /// Prover is able to prove this because get_validator_index_ ensures it + /// in calling context. + requires 0 <= i && i < len(validators); + /// Somewhat simplified from the code because of properties guaranteed + /// by the calling context. + ensures + result == + (ValidatorConfig::is_valid(validators[i].addr) && + new_validator_config != old(validators[i].config)); + /// It only updates validators at index `i`, and updates the + /// `config` field to `new_validator_config`. + ensures + result ==> + validators == update( + old(validators), + i, + update_field(old(validators[i]), config, new_validator_config) + ); + /// Does not change validators if result is false + ensures !result ==> validators == old(validators); + /// Updates the ith validator entry (and nothing else), as appropriate. + ensures validators == update(old(validators), i, validators[i]); + /// Needed these assertions to make "consensus voting power is always 1" invariant + /// prove (not sure why). + requires forall i1 in 0..len(spec_get_validators()): + spec_get_validators()[i1].consensus_voting_power == 1; + ensures forall i1 in 0..len(spec_get_validators()): + spec_get_validators()[i1].consensus_voting_power == 1; + } + + /// Private function checks for membership of `addr` in validator set. + fun is_validator_(addr: address, validators_vec_ref: &vector): bool { + option::is_some(&get_validator_index_(validators_vec_ref, addr)) + } + spec is_validator_ { + pragma opaque; + aborts_if false; + ensures result == (exists v in validators_vec_ref: v.addr == addr); + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Initialization + spec module { + /// After genesis, the `DiemSystem` configuration is published, as well as the capability + /// which grants the right to modify it to certain functions in this module. + invariant [suspendable] DiemTimestamp::is_operating() ==> + DiemConfig::spec_is_published() && + exists(@DiemRoot); + } + + /// # Access Control + + /// Access control requirements for validator set are a bit more complicated than + /// many parts of the framework because of `update_config_and_reconfigure`. + /// That function updates the validator info (e.g., the network address) for a + /// particular Validator Owner, but only if the signer is the Operator for that owner. + /// Therefore, we must ensure that the information for other validators in the + /// validator set are not changed, which is specified locally for + /// `update_config_and_reconfigure`. + + spec module { + invariant forall addr: address + where exists>(addr): addr == @DiemRoot; + + invariant update [suspendable] ( + old(DiemConfig::spec_is_published()) && + DiemConfig::spec_is_published() && + old(len(DiemConfig::get().validators)) != len(DiemConfig::get().validators) + ) ==> Roles::spec_signed_by_diem_root_role(); + + invariant update [suspendable] ( + old(DiemConfig::spec_is_published()) && + DiemConfig::spec_is_published() && + old(len(DiemConfig::get().validators)) == len(DiemConfig::get().validators) + ) ==> ( + forall addr: address: ( + exists i in 0..len(DiemConfig::get().validators) + where old(DiemConfig::get().validators[i].addr == addr): + old(DiemConfig::get().validators[i].config) != DiemConfig::get().validators[i].config + ) ==> (exists a: address: signer::is_txn_signer_addr(a) && ValidatorConfig::get_operator(addr) == a) + ); + } + + // TODO: The following is the old style spec, which can removed later. + spec module { + /// The permission "{Add, Remove} Validator" is granted to DiemRoot [[H14]][PERMISSION]. + apply Roles::AbortsIfNotDiemRoot{account: dr_account} to add_validator, remove_validator; + /// The permission "UpdateValidatorConfig(addr)" is granted to ValidatorOperator [[H15]][PERMISSION] + apply Roles::AbortsIfNotValidatorOperator{account: validator_operator_account} to update_config_and_reconfigure; + } + spec schema ValidatorSetConfigRemainsSame { + ensures spec_get_validators() == old(spec_get_validators()); + } + spec module { + /// Only {add, remove} validator [[H14]][PERMISSION] and update_config_and_reconfigure + /// [[H15]][PERMISSION] may change the set of validators in the configuration. + /// `set_diem_system_config` is a private function which is only called by other + /// functions in the "except" list. `initialize_validator_set` is only called in + /// Genesis. + apply ValidatorSetConfigRemainsSame to *, * + except add_validator, remove_validator, update_config_and_reconfigure, + initialize_validator_set, set_diem_system_config; + } + + /// # Helper Functions + + /// Fetches the currently published validator set from the published DiemConfig + /// resource. + spec fun spec_get_validators(): vector { + DiemConfig::get().validators + } + + spec fun spec_index_of_validator(validators: vector, addr: address): u64 { + choose min i in range(validators) where validators[i].addr == addr + } + + spec module { + + /// Every validator has a published ValidatorConfig whose config option is "some" + /// (meaning of ValidatorConfig::is_valid). + /// > Unfortunately, this times out for unknown reasons (it doesn't seem to be hard), + /// so it is deactivated. + /// The Prover can prove it if the uniqueness invariant for the DiemSystem resource + /// is commented out, along with aborts for update_config_and_reconfigure and everything + /// else that breaks (e.g., there is an ensures in remove_validator that has to be + /// commented out) + invariant [deactivated, global] forall i1 in 0..len(spec_get_validators()): + ValidatorConfig::is_valid(spec_get_validators()[i1].addr); + + /// Every validator in the validator set has a validator role. + /// > Note: Verification of DiemSystem seems to be very sensitive, and will + /// often time out after small changes. Disabling this property + /// (with [deactivate, global]) is sometimes a quick temporary fix. + invariant [suspendable] forall i1 in 0..len(spec_get_validators()): + Roles::spec_has_validator_role_addr(spec_get_validators()[i1].addr); + + /// `Consensus_voting_power` is always 1. In future implementations, this + /// field may have different values in which case this property will have to + /// change. It's here currently because and accidental or illicit change + /// to the voting power of a validator could defeat the Byzantine fault tolerance + /// of DiemBFT. + invariant [suspendable] forall i1 in 0..len(spec_get_validators()): + spec_get_validators()[i1].consensus_voting_power == 1; + + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemTimestamp.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemTimestamp.move new file mode 100644 index 000000000..780bc43dd --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemTimestamp.move @@ -0,0 +1,196 @@ +/// This module keeps a global wall clock that stores the current Unix time in microseconds. +/// It interacts with the other modules in the following ways: +/// +/// * Genesis: to initialize the timestamp +/// * VASP: to keep track of when credentials expire +/// * DiemSystem, DiemAccount, DiemConfig: to check if the current state is in the genesis state +/// * DiemBlock: to reach consensus on the global wall clock time +/// * AccountLimits: to limit the time of account limits +/// +/// This module moreover enables code to assert that it is running in genesis (`Self::assert_genesis`) or after +/// genesis (`Self::assert_operating`). These are essentially distinct states of the system. Specifically, +/// if `Self::assert_operating` succeeds, assumptions about invariants over the global state can be made +/// which reflect that the system has been successfully initialized. +module DiemFramework::DiemTimestamp { + use DiemFramework::CoreAddresses; + use std::errors; + friend DiemFramework::Genesis; + + /// A singleton resource holding the current Unix time in microseconds + struct CurrentTimeMicroseconds has key { + microseconds: u64, + } + + /// Conversion factor between seconds and microseconds + const MICRO_CONVERSION_FACTOR: u64 = 1000000; + + /// The blockchain is not in the genesis state anymore + const ENOT_GENESIS: u64 = 0; + /// The blockchain is not in an operating state yet + const ENOT_OPERATING: u64 = 1; + /// An invalid timestamp was provided + const ETIMESTAMP: u64 = 2; + + /// Marks that time has started and genesis has finished. This can only be called from genesis and with the root + /// account. + public(friend) fun set_time_has_started(dr_account: &signer) { + assert_genesis(); + CoreAddresses::assert_diem_root(dr_account); + let timer = CurrentTimeMicroseconds { microseconds: 0 }; + move_to(dr_account, timer); + } + spec set_time_has_started { + /// This function can't be verified on its own and has to be verified in the context of Genesis execution. + /// + /// After time has started, all invariants guarded by `DiemTimestamp::is_operating` will become activated + /// and need to hold. + pragma delegate_invariants_to_caller; + include AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + ensures is_operating(); + ensures spec_now_microseconds() == 0; + } + + // TODO: this is for both df-cli and the unit-test for df + // - df-cli, as a few test cases in df-cli uses a customized genesis module and that module needs to invoke + // `set_time_has_started` in order to complete the genesis process. Until we find a way to solve this issue, this + // temporary function will stay here. + // - this is also needed for diem-framework unit test `DiemTimestampTests`. And once the above issue for df-cli is + // resolved, we can mark this function #[test_only] + public fun set_time_has_started_for_testing(dr_account: &signer) { + set_time_has_started(dr_account); + } + spec set_time_has_started_for_testing { + pragma verify = false; + } + + /// Updates the wall clock time by consensus. Requires VM privilege and will be invoked during block prologue. + public fun update_global_time( + account: &signer, + proposer: address, + timestamp: u64 + ) acquires CurrentTimeMicroseconds { + assert_operating(); + // Can only be invoked by DiemVM signer. + CoreAddresses::assert_vm(account); + + let global_timer = borrow_global_mut(@DiemRoot); + let now = global_timer.microseconds; + if (proposer == @VMReserved) { + // NIL block with null address as proposer. Timestamp must be equal. + assert!(now == timestamp, errors::invalid_argument(ETIMESTAMP)); + } else { + // Normal block. Time must advance + assert!(now < timestamp, errors::invalid_argument(ETIMESTAMP)); + }; + global_timer.microseconds = timestamp; + } + spec update_global_time { + pragma opaque; + modifies global(@DiemRoot); + + let now = spec_now_microseconds(); + let post post_now = spec_now_microseconds(); + + /// Conditions unique for abstract and concrete version of this function. + include AbortsIfNotOperating; + include CoreAddresses::AbortsIfNotVM; + ensures post_now == timestamp; + + /// Conditions we only check for the implementation, but do not pass to the caller. + aborts_if [concrete] + (if (proposer == @VMReserved) { + now != timestamp + } else { + now >= timestamp + } + ) + with errors::INVALID_ARGUMENT; + } + + /// Gets the current time in microseconds. + public fun now_microseconds(): u64 acquires CurrentTimeMicroseconds { + assert_operating(); + borrow_global(@DiemRoot).microseconds + } + spec now_microseconds { + pragma opaque; + include AbortsIfNotOperating; + ensures result == spec_now_microseconds(); + } + spec fun spec_now_microseconds(): u64 { + global(@DiemRoot).microseconds + } + + /// Gets the current time in seconds. + public fun now_seconds(): u64 acquires CurrentTimeMicroseconds { + now_microseconds() / MICRO_CONVERSION_FACTOR + } + spec now_seconds { + pragma opaque; + include AbortsIfNotOperating; + ensures result == spec_now_seconds(); + } + spec fun spec_now_seconds(): u64 { + spec_now_microseconds() / MICRO_CONVERSION_FACTOR + } + + /// Helper function to determine if Diem is in genesis state. + public fun is_genesis(): bool { + !exists(@DiemRoot) + } + + /// Helper function to assert genesis state. + public fun assert_genesis() { + assert!(is_genesis(), errors::invalid_state(ENOT_GENESIS)); + } + spec assert_genesis { + pragma opaque = true; + include AbortsIfNotGenesis; + } + + /// Helper schema to specify that a function aborts if not in genesis. + spec schema AbortsIfNotGenesis { + aborts_if !is_genesis() with errors::INVALID_STATE; + } + + /// Helper function to determine if Diem is operating. This is the same as `!is_genesis()` and is provided + /// for convenience. Testing `is_operating()` is more frequent than `is_genesis()`. + public fun is_operating(): bool { + exists(@DiemRoot) + } + + /// Helper function to assert operating (!genesis) state. + public fun assert_operating() { + assert!(is_operating(), errors::invalid_state(ENOT_OPERATING)); + } + spec assert_operating { + pragma opaque = true; + include AbortsIfNotOperating; + } + + /// Helper schema to specify that a function aborts if not operating. + spec schema AbortsIfNotOperating { + aborts_if !is_operating() with errors::INVALID_STATE; + } + + // ==================== + // Module Specification + spec module {} // switch documentation context to module level + + spec module { + /// After genesis, `CurrentTimeMicroseconds` is published forever + invariant is_operating() ==> exists(@DiemRoot); + + /// After genesis, time progresses monotonically. + invariant update + old(is_operating()) ==> old(spec_now_microseconds()) <= spec_now_microseconds(); + } + + spec module { + /// All functions which do not have an `aborts_if` specification in this module are implicitly declared + /// to never abort. + pragma aborts_if_is_strict; + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemTransactionPublishingOption.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemTransactionPublishingOption.move new file mode 100644 index 000000000..04ca1d134 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemTransactionPublishingOption.move @@ -0,0 +1,195 @@ +/// This module defines a struct storing the publishing policies for the VM. +module DiemFramework::DiemTransactionPublishingOption { + use DiemFramework::DiemConfig::{Self, DiemConfig}; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::errors; + use std::signer; + use std::vector; + + const SCRIPT_HASH_LENGTH: u64 = 32; + + /// The script hash has an invalid length + const EINVALID_SCRIPT_HASH: u64 = 0; + /// The script hash already exists in the allowlist + const EALLOWLIST_ALREADY_CONTAINS_SCRIPT: u64 = 1; + /// Attempting to publish/unpublish a HaltAllTransactions resource that does not exist. + const EHALT_ALL_TRANSACTIONS: u64 = 2; + + /// Defines and holds the publishing policies for the VM. There are three possible configurations: + /// 1. No module publishing, only allow-listed scripts are allowed. + /// 2. No module publishing, custom scripts are allowed. + /// 3. Both module publishing and custom scripts are allowed. + /// We represent these as the following resource. + struct DiemTransactionPublishingOption has copy, drop, store { + /// Only script hashes in the following list can be executed by the network. If the vector is empty, no + /// limitation would be enforced. + script_allow_list: vector>, + /// Anyone can publish new module if this flag is set to true. + module_publishing_allowed: bool, + } + + /// If published, halts transactions from all accounts except DiemRoot + struct HaltAllTransactions has key {} + + public fun initialize( + dr_account: &signer, + script_allow_list: vector>, + module_publishing_allowed: bool, + ) { + DiemTimestamp::assert_genesis(); + Roles::assert_diem_root(dr_account); + + DiemConfig::publish_new_config( + dr_account, + DiemTransactionPublishingOption { + script_allow_list, module_publishing_allowed + } + ); + } + spec initialize { + /// Must abort if the signer does not have the DiemRoot role [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemTimestamp::AbortsIfNotGenesis; + include DiemConfig::PublishNewConfigAbortsIf; + include DiemConfig::PublishNewConfigEnsures { + payload: DiemTransactionPublishingOption { + script_allow_list, module_publishing_allowed + }}; + } + + /// Check if sender can execute script with `hash` + public fun is_script_allowed(account: &signer, hash: &vector): bool { + // DiemRoot can send any script + if (Roles::has_diem_root_role(account)) return true; + + // No one except DiemRoot can send scripts when transactions are halted + if (transactions_halted()) return false; + + // The adapter passes an empty hash for script functions. All script functions are allowed + if (vector::is_empty(hash)) return true; + + let publish_option = DiemConfig::get(); + // allowlist empty = open publishing, anyone can send txes + vector::is_empty(&publish_option.script_allow_list) + // fixed allowlist. check inclusion + || vector::contains(&publish_option.script_allow_list, hash) + } + spec is_script_allowed { + include + !Roles::has_diem_root_role(account) && !transactions_halted() && !vector::is_empty(hash) + ==> DiemConfig::AbortsIfNotPublished{}; + } + spec schema AbortsIfNoTransactionPublishingOption { + include DiemTimestamp::is_genesis() ==> DiemConfig::AbortsIfNotPublished{}; + } + + /// Check if a sender can publish a module + public fun is_module_allowed(account: &signer): bool { + let publish_option = DiemConfig::get(); + + publish_option.module_publishing_allowed || Roles::has_diem_root_role(account) + } + spec is_module_allowed{ + include DiemConfig::AbortsIfNotPublished{}; + } + + /// Allow the execution of arbitrary script or not. + public fun set_open_script(dr_account: &signer) { + Roles::assert_diem_root(dr_account); + let publish_option = DiemConfig::get(); + + publish_option.script_allow_list = vector::empty(); + DiemConfig::set(dr_account, publish_option); + } + spec set_open_script { + /// Must abort if the signer does not have the DiemRoot role [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemConfig::AbortsIfNotPublished; + include DiemConfig::SetAbortsIf{account: dr_account}; + } + + /// Allow module publishing from arbitrary sender or not. + public fun set_open_module(dr_account: &signer, open_module: bool) { + Roles::assert_diem_root(dr_account); + + let publish_option = DiemConfig::get(); + + publish_option.module_publishing_allowed = open_module; + DiemConfig::set(dr_account, publish_option); + } + spec set_open_module { + /// Must abort if the signer does not have the DiemRoot role [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemConfig::AbortsIfNotPublished; + include DiemConfig::SetAbortsIf{account: dr_account}; + } + + /// If called, transactions cannot be sent from any account except DiemRoot + public fun halt_all_transactions(dr_account: &signer) { + Roles::assert_diem_root(dr_account); + assert!( + !exists(signer::address_of(dr_account)), + errors::already_published(EHALT_ALL_TRANSACTIONS), + ); + move_to(dr_account, HaltAllTransactions {}); + } + + /// If called, transactions can be sent from any account once again + public fun resume_transactions(dr_account: &signer) acquires HaltAllTransactions { + Roles::assert_diem_root(dr_account); + let dr_address = signer::address_of(dr_account); + assert!( + exists(dr_address), + errors::already_published(EHALT_ALL_TRANSACTIONS), + ); + + let HaltAllTransactions {} = move_from(dr_address); + } + + /// Return true if all non-administrative transactions are currently halted + fun transactions_halted(): bool { + exists(@DiemRoot) + } + + spec module { } // Switch documentation context to module level. + + /// # Initialization + spec module { + invariant [suspendable] DiemTimestamp::is_operating() ==> + DiemConfig::spec_is_published(); + } + + /// # Access Control + + /// Only `set_open_script`, and `set_open_module` can modify the + /// DiemTransactionPublishingOption config [[H11]][PERMISSION] + spec schema DiemVersionRemainsSame { + ensures old(DiemConfig::spec_is_published()) ==> + global>(@DiemRoot) == + old(global>(@DiemRoot)); + } + spec module { + apply DiemVersionRemainsSame to * except set_open_script, set_open_module; + } + + /// # Helper Functions + spec module { + fun spec_is_script_allowed(account: signer, hash: vector): bool { + let publish_option = DiemConfig::spec_get_config(); + Roles::has_diem_root_role(account) || (!transactions_halted() && ( + vector::is_empty(hash) || + (vector::is_empty(publish_option.script_allow_list) + || contains(publish_option.script_allow_list, hash)) + )) + } + + fun spec_is_module_allowed(account: signer): bool { + let publish_option = DiemConfig::spec_get_config(); + publish_option.module_publishing_allowed || Roles::has_diem_root_role(account) + } + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemVMConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemVMConfig.move new file mode 100644 index 000000000..e022fd08d --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemVMConfig.move @@ -0,0 +1,242 @@ +/// This module defines structs and methods to initialize VM configurations, +/// including different costs of running the VM. +module DiemFramework::DiemVMConfig { + use DiemFramework::DiemConfig::{Self, DiemConfig}; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::errors; + + /// The provided gas constants were inconsistent. + const EGAS_CONSTANT_INCONSISTENCY: u64 = 0; + + /// The struct to hold config data needed to operate the DiemVM. + struct DiemVMConfig has copy, drop, store { + /// Cost of running the VM. + gas_schedule: GasSchedule, + } + + /// The gas schedule keeps two separate schedules for the gas: + /// * The instruction_schedule: This holds the gas for each bytecode instruction. + /// * The native_schedule: This holds the gas for used (per-byte operated over) for each native + /// function. + /// A couple notes: + /// 1. In the case that an instruction is deleted from the bytecode, that part of the cost schedule + /// still needs to remain the same; once a slot in the table is taken by an instruction, that is its + /// slot for the rest of time (since that instruction could already exist in a module on-chain). + /// 2. The initialization of the module will publish the instruction table to the diem root account + /// address, and will preload the vector with the gas schedule for instructions. The VM will then + /// load this into memory at the startup of each block. + struct GasSchedule has copy, drop, store { + instruction_schedule: vector, + native_schedule: vector, + gas_constants: GasConstants, + } + + struct GasConstants has copy, drop, store { + /// The cost per-byte read from global storage. + global_memory_per_byte_cost: u64, + + /// The cost per-byte written to storage. + global_memory_per_byte_write_cost: u64, + + /// The flat minimum amount of gas required for any transaction. + /// Charged at the start of execution. + min_transaction_gas_units: u64, + + /// Any transaction over this size will be charged an additional amount per byte. + large_transaction_cutoff: u64, + + /// The units of gas to be charged per byte over the `large_transaction_cutoff` in addition to + /// `min_transaction_gas_units` for transactions whose size exceeds `large_transaction_cutoff`. + intrinsic_gas_per_byte: u64, + + /// ~5 microseconds should equal one unit of computational gas. We bound the maximum + /// computational time of any given transaction at roughly 20 seconds. We want this number and + /// `MAX_PRICE_PER_GAS_UNIT` to always satisfy the inequality that + /// MAXIMUM_NUMBER_OF_GAS_UNITS * MAX_PRICE_PER_GAS_UNIT < min(u64::MAX, GasUnits::MAX) + /// NB: The bound is set quite high since custom scripts aren't allowed except from predefined + /// and vetted senders. + maximum_number_of_gas_units: u64, + + /// The minimum gas price that a transaction can be submitted with. + min_price_per_gas_unit: u64, + + /// The maximum gas unit price that a transaction can be submitted with. + max_price_per_gas_unit: u64, + + max_transaction_size_in_bytes: u64, + gas_unit_scaling_factor: u64, + default_account_size: u64, + } + + /// Initialize the table under the diem root account + public fun initialize( + dr_account: &signer, + instruction_schedule: vector, + native_schedule: vector, + ) { + DiemTimestamp::assert_genesis(); + + // The permission "UpdateVMConfig" is granted to DiemRoot [[H11]][PERMISSION]. + Roles::assert_diem_root(dr_account); + + let gas_constants = GasConstants { + global_memory_per_byte_cost: 4, + global_memory_per_byte_write_cost: 9, + min_transaction_gas_units: 600, + large_transaction_cutoff: 600, + intrinsic_gas_per_byte: 8, + maximum_number_of_gas_units: 4000000, + min_price_per_gas_unit: 0, + max_price_per_gas_unit: 10000, + max_transaction_size_in_bytes: 4096, + gas_unit_scaling_factor: 1000, + default_account_size: 800, + }; + + DiemConfig::publish_new_config( + dr_account, + DiemVMConfig { + gas_schedule: GasSchedule { + instruction_schedule, + native_schedule, + gas_constants, + } + }, + ); + } + spec initialize { + let gas_constants = GasConstants { + global_memory_per_byte_cost: 4, + global_memory_per_byte_write_cost: 9, + min_transaction_gas_units: 600, + large_transaction_cutoff: 600, + intrinsic_gas_per_byte: 8, + maximum_number_of_gas_units: 4000000, + min_price_per_gas_unit: 0, + max_price_per_gas_unit: 10000, + max_transaction_size_in_bytes: 4096, + gas_unit_scaling_factor: 1000, + default_account_size: 800, + }; + + /// Must abort if the signer does not have the DiemRoot role [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemTimestamp::AbortsIfNotGenesis; + include DiemConfig::PublishNewConfigAbortsIf; + include DiemConfig::PublishNewConfigEnsures { + payload: DiemVMConfig { + gas_schedule: GasSchedule { + instruction_schedule, + native_schedule, + gas_constants, + } + }}; + } + + public fun set_gas_constants( + dr_account: &signer, + global_memory_per_byte_cost: u64, + global_memory_per_byte_write_cost: u64, + min_transaction_gas_units: u64, + large_transaction_cutoff: u64, + intrinsic_gas_per_byte: u64, + maximum_number_of_gas_units: u64, + min_price_per_gas_unit: u64, + max_price_per_gas_unit: u64, + max_transaction_size_in_bytes: u64, + gas_unit_scaling_factor: u64, + default_account_size: u64, + ) { + DiemTimestamp::assert_operating(); + Roles::assert_diem_root(dr_account); + assert!( + min_price_per_gas_unit <= max_price_per_gas_unit, + errors::invalid_argument(EGAS_CONSTANT_INCONSISTENCY) + ); + assert!( + min_transaction_gas_units <= maximum_number_of_gas_units, + errors::invalid_argument(EGAS_CONSTANT_INCONSISTENCY) + ); + + let config = DiemConfig::get(); + let gas_constants = &mut config.gas_schedule.gas_constants; + + gas_constants.global_memory_per_byte_cost = global_memory_per_byte_cost; + gas_constants.global_memory_per_byte_write_cost = global_memory_per_byte_write_cost; + gas_constants.min_transaction_gas_units = min_transaction_gas_units; + gas_constants.large_transaction_cutoff = large_transaction_cutoff; + gas_constants.intrinsic_gas_per_byte = intrinsic_gas_per_byte; + gas_constants.maximum_number_of_gas_units = maximum_number_of_gas_units; + gas_constants.min_price_per_gas_unit = min_price_per_gas_unit; + gas_constants.max_price_per_gas_unit = max_price_per_gas_unit; + gas_constants.max_transaction_size_in_bytes = max_transaction_size_in_bytes; + gas_constants.gas_unit_scaling_factor = gas_unit_scaling_factor; + gas_constants.default_account_size = default_account_size; + + DiemConfig::set(dr_account, config); + } + spec set_gas_constants { + include DiemTimestamp::AbortsIfNotOperating; + /// No one can update DiemVMConfig except for the Diem Root account [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include DiemConfig::SetAbortsIf{account: dr_account }; + aborts_if min_price_per_gas_unit > max_price_per_gas_unit with errors::INVALID_ARGUMENT; + aborts_if min_transaction_gas_units > maximum_number_of_gas_units with errors::INVALID_ARGUMENT; + let config = DiemConfig::spec_get_config(); + ensures DiemConfig::spec_is_published(); + ensures DiemConfig::get() == DiemVMConfig { + gas_schedule: GasSchedule { + instruction_schedule: config.gas_schedule.instruction_schedule, + native_schedule: config.gas_schedule.native_schedule, + gas_constants: GasConstants { + global_memory_per_byte_cost, + global_memory_per_byte_write_cost, + min_transaction_gas_units, + large_transaction_cutoff, + intrinsic_gas_per_byte, + maximum_number_of_gas_units, + min_price_per_gas_unit, + max_price_per_gas_unit, + max_transaction_size_in_bytes, + gas_unit_scaling_factor, + default_account_size, + }, + } + }; + ensures old(DiemConfig::spec_has_config()) == DiemConfig::spec_has_config(); + } + + spec module { } // Switch documentation context to module level. + + /// # Initialization + + spec module { + invariant [suspendable] DiemTimestamp::is_operating() ==> DiemConfig::spec_is_published(); + } + + /// # Access Control + + /// The permission "UpdateVMConfig" is granted to DiemRoot [[H11]][PERMISSION]. + spec module { + invariant [suspendable] forall addr: address + where exists>(addr): addr == @DiemRoot; + + invariant update [suspendable] old(DiemConfig::spec_is_published()) + && DiemConfig::spec_is_published() + && old(DiemConfig::get()) != DiemConfig::get() + ==> Roles::spec_signed_by_diem_root_role(); + } + + // TODO: The following is the old style spec, which can removed later. + /// No one can update DiemVMConfig except for the Diem Root account [[H11]][PERMISSION]. + spec schema DiemVMConfigRemainsSame { + ensures old(DiemConfig::spec_is_published()) ==> + global>(@DiemRoot) == + old(global>(@DiemRoot)); + } + spec module { + apply DiemVMConfigRemainsSame to * except set_gas_constants; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemVersion.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemVersion.move new file mode 100644 index 000000000..ce3d9942c --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DiemVersion.move @@ -0,0 +1,106 @@ +/// Maintains the version number for the Diem blockchain. The version is stored in a +/// DiemConfig, and may be updated by Diem root. +module DiemFramework::DiemVersion { + use DiemFramework::DiemConfig::{Self, DiemConfig}; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::errors; + + struct DiemVersion has copy, drop, store { + major: u64, + } + + /// Tried to set an invalid major version for the VM. Major versions must be strictly increasing + const EINVALID_MAJOR_VERSION_NUMBER: u64 = 0; + + /// Publishes the DiemVersion config. Must be called during Genesis. + public fun initialize(dr_account: &signer, initial_version: u64) { + DiemTimestamp::assert_genesis(); + Roles::assert_diem_root(dr_account); + DiemConfig::publish_new_config( + dr_account, + DiemVersion { major: initial_version }, + ); + } + spec initialize { + /// Must abort if the signer does not have the DiemRoot role [[H10]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemTimestamp::AbortsIfNotGenesis; + include DiemConfig::PublishNewConfigAbortsIf; + include DiemConfig::PublishNewConfigEnsures{payload: DiemVersion { major: initial_version }}; + } + + /// Allows Diem root to update the major version to a larger version. + public fun set(dr_account: &signer, major: u64) { + DiemTimestamp::assert_operating(); + + Roles::assert_diem_root(dr_account); + + let old_config = DiemConfig::get(); + + assert!( + old_config.major < major, + errors::invalid_argument(EINVALID_MAJOR_VERSION_NUMBER) + ); + + DiemConfig::set( + dr_account, + DiemVersion { major } + ); + } + spec set { + /// Must abort if the signer does not have the DiemRoot role [[H10]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemTimestamp::AbortsIfNotOperating; + aborts_if DiemConfig::get().major >= major with errors::INVALID_ARGUMENT; + include DiemConfig::SetAbortsIf{account: dr_account}; + include DiemConfig::SetEnsures{payload: DiemVersion { major }}; + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Initialization + spec module { + /// After genesis, version is published. + invariant [suspendable] DiemTimestamp::is_operating() ==> DiemConfig::spec_is_published(); + } + + /// # Access Control + + /// The permission "UpdateDiemProtocolVersion" is granted to DiemRoot [[H10]][PERMISSION]. + spec module { + invariant [suspendable] forall addr: address + where exists>(addr): addr == @DiemRoot; + + invariant update [suspendable] old(DiemConfig::spec_is_published()) + && DiemConfig::spec_is_published() + && old(DiemConfig::get().major) != DiemConfig::get().major + ==> Roles::spec_signed_by_diem_root_role(); + } + + // TODO: The following is the old style spec, which can removed later. + /// Only "set" can modify the DiemVersion config [[H10]][PERMISSION] + spec schema DiemVersionRemainsSame { + ensures old(DiemConfig::spec_is_published()) ==> + global>(@DiemRoot) == + old(global>(@DiemRoot)); + } + /// The permission "UpdateDiemProtocolVersion" is granted to DiemRoot [[H10]][PERMISSION]. + spec module { + apply DiemVersionRemainsSame to * except set; + } + + /// # Other Invariants + spec module { + /// Version number never decreases + invariant update [suspendable] + DiemTimestamp::is_operating() ==> + (old(DiemConfig::get().major) <= DiemConfig::get().major); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DualAttestation.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DualAttestation.move new file mode 100644 index 000000000..f440d6bae --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/DualAttestation.move @@ -0,0 +1,584 @@ +/// Module managing dual attestation. +module DiemFramework::DualAttestation { + use DiemFramework::CoreAddresses; + use DiemFramework::XDX::XDX; + use DiemFramework::Diem; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use DiemFramework::Signature; + use DiemFramework::VASP; + use std::bcs; + use std::errors; + use std::event::{Self, EventHandle}; + use std::signer; + use std::vector; + friend DiemFramework::DiemAccount; + + /// This resource holds an entity's globally unique name and all of the metadata it needs to + /// participate in off-chain protocols. + struct Credential has key { + /// The human readable name of this entity. Immutable. + human_name: vector, + /// The base_url holds the URL to be used for off-chain communication. This contains the + /// entire URL. Mutable. + base_url: vector, + /// 32 byte Ed25519 public key whose counterpart must be used to sign + /// (1) the payment metadata for on-chain transactions that require dual attestation (e.g., + /// transactions subject to the travel rule) + /// (2) information exchanged in the off-chain protocols (e.g., KYC info in the travel rule + /// protocol) + /// Note that this is different than `authentication_key` used in DiemAccount, which is + /// a hash of a public key + signature scheme identifier, not a public key. Mutable. + compliance_public_key: vector, + /// Expiration date in microseconds from unix epoch. For V1, it is always set to + /// U64_MAX. Mutable, but only by DiemRoot. + expiration_date: u64, + /// Event handle for `compliance_public_key` rotation events. Emitted + /// every time this `compliance_public_key` is rotated. + compliance_key_rotation_events: EventHandle, + /// Event handle for `base_url` rotation events. Emitted every time this `base_url` is rotated. + base_url_rotation_events: EventHandle, + } + + /// Struct to store the limit on-chain + struct Limit has key { + micro_xdx_limit: u64, + } + + /// The message sent whenever the compliance public key for a `DualAttestation` resource is rotated. + struct ComplianceKeyRotationEvent has drop, store { + /// The new `compliance_public_key` that is being used for dual attestation checking. + new_compliance_public_key: vector, + /// The time at which the `compliance_public_key` was rotated + time_rotated_seconds: u64, + } + + /// The message sent whenever the base url for a `DualAttestation` resource is rotated. + struct BaseUrlRotationEvent has drop, store { + /// The new `base_url` that is being used for dual attestation checking + new_base_url: vector, + /// The time at which the `base_url` was rotated + time_rotated_seconds: u64, + } + + const MAX_U64: u128 = 18446744073709551615; + + // Error codes + /// A credential is not or already published. + const ECREDENTIAL: u64 = 0; + /// A limit is not or already published. + const ELIMIT: u64 = 1; + /// Cannot parse this as an ed25519 public key + const EINVALID_PUBLIC_KEY: u64 = 2; + /// Cannot parse this as an ed25519 signature (e.g., != 64 bytes) + const EMALFORMED_METADATA_SIGNATURE: u64 = 3; + /// Signature does not match message and public key + const EINVALID_METADATA_SIGNATURE: u64 = 4; + /// The recipient of a dual attestation payment needs to set a compliance public key + const EPAYEE_COMPLIANCE_KEY_NOT_SET: u64 = 5; + /// The recipient of a dual attestation payment needs to set a base URL + const EPAYEE_BASE_URL_NOT_SET: u64 = 6; + + /// Value of the dual attestation limit at genesis + const INITIAL_DUAL_ATTESTATION_LIMIT: u64 = 1000; + /// Suffix of every signed dual attestation message + const DOMAIN_SEPARATOR: vector = b"@@$$DIEM_ATTEST$$@@"; + /// A year in microseconds + const ONE_YEAR: u64 = 31540000000000; + const U64_MAX: u64 = 18446744073709551615; + + /// Publish a `Credential` resource with name `human_name` under `created` with an empty + /// `base_url` and `compliance_public_key`. Before receiving any dual attestation payments, + /// the `created` account must send a transaction that invokes `rotate_base_url` and + /// `rotate_compliance_public_key` to set these fields to a valid URL/public key. + public(friend) fun publish_credential( + created: &signer, + creator: &signer, + human_name: vector, + ) { + Roles::assert_parent_vasp_or_designated_dealer(created); + Roles::assert_treasury_compliance(creator); + assert!( + !exists(signer::address_of(created)), + errors::already_published(ECREDENTIAL) + ); + move_to(created, Credential { + human_name, + base_url: vector::empty(), + compliance_public_key: vector::empty(), + // For testnet and V1, so it should never expire. So set to u64::MAX + expiration_date: U64_MAX, + compliance_key_rotation_events: event::new_event_handle(created), + base_url_rotation_events: event::new_event_handle(created), + }) + } + spec publish_credential { + /// The permission "RotateDualAttestationInfo" is granted to ParentVASP and DesignatedDealer [[H17]][PERMISSION]. + include Roles::AbortsIfNotParentVaspOrDesignatedDealer{account: created}; + include Roles::AbortsIfNotTreasuryCompliance{account: creator}; + aborts_if spec_has_credential(signer::address_of(created)) with errors::ALREADY_PUBLISHED; + } + spec fun spec_has_credential(addr: address): bool { + exists(addr) + } + + /// Rotate the base URL for `account` to `new_url` + public fun rotate_base_url(account: &signer, new_url: vector) acquires Credential { + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(ECREDENTIAL)); + let credential = borrow_global_mut(addr); + credential.base_url = copy new_url; + event::emit_event(&mut credential.base_url_rotation_events, BaseUrlRotationEvent { + new_base_url: new_url, + time_rotated_seconds: DiemTimestamp::now_seconds(), + }); + } + spec rotate_base_url { + include RotateBaseUrlAbortsIf; + include RotateBaseUrlEnsures; + include RotateBaseUrlEmits; + } + spec schema RotateBaseUrlAbortsIf { + account: signer; + let sender = signer::address_of(account); + + /// Must abort if the account does not have the resource Credential [[H17]][PERMISSION]. + include AbortsIfNoCredential{addr: sender}; + + include DiemTimestamp::AbortsIfNotOperating; + } + spec schema AbortsIfNoCredential { + addr: address; + aborts_if !spec_has_credential(addr) with errors::NOT_PUBLISHED; + } + spec schema RotateBaseUrlEnsures { + account: signer; + new_url: vector; + let sender = signer::address_of(account); + + ensures global(sender).base_url == new_url; + /// The sender can only rotate its own base url [[H17]][PERMISSION]. + ensures forall addr1:address where addr1 != sender: + global(addr1).base_url == old(global(addr1).base_url); + } + spec schema RotateBaseUrlEmits { + account: signer; + new_url: vector; + let sender = signer::address_of(account); + let handle = global(sender).base_url_rotation_events; + let msg = BaseUrlRotationEvent { + new_base_url: new_url, + time_rotated_seconds: DiemTimestamp::spec_now_seconds(), + }; + emits msg to handle; + } + + /// Rotate the compliance public key for `account` to `new_key`. + public fun rotate_compliance_public_key( + account: &signer, + new_key: vector, + ) acquires Credential { + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(ECREDENTIAL)); + assert!(Signature::ed25519_validate_pubkey(copy new_key), errors::invalid_argument(EINVALID_PUBLIC_KEY)); + let credential = borrow_global_mut(addr); + credential.compliance_public_key = copy new_key; + event::emit_event(&mut credential.compliance_key_rotation_events, ComplianceKeyRotationEvent { + new_compliance_public_key: new_key, + time_rotated_seconds: DiemTimestamp::now_seconds(), + }); + + } + spec rotate_compliance_public_key { + include RotateCompliancePublicKeyAbortsIf; + include RotateCompliancePublicKeyEnsures; + include RotateCompliancePublicKeyEmits; + } + spec schema RotateCompliancePublicKeyAbortsIf { + account: signer; + new_key: vector; + + let sender = signer::address_of(account); + /// Must abort if the account does not have the resource Credential [[H17]][PERMISSION]. + include AbortsIfNoCredential{addr: sender}; + + include DiemTimestamp::AbortsIfNotOperating; + aborts_if !Signature::ed25519_validate_pubkey(new_key) with errors::INVALID_ARGUMENT; + } + spec schema RotateCompliancePublicKeyEnsures { + account: signer; + new_key: vector; + + let sender = signer::address_of(account); + ensures global(sender).compliance_public_key == new_key; + /// The sender only rotates its own compliance_public_key [[H17]][PERMISSION]. + ensures forall addr1: address where addr1 != sender: + global(addr1).compliance_public_key == old(global(addr1).compliance_public_key); + } + spec schema RotateCompliancePublicKeyEmits { + account: signer; + new_key: vector; + let sender = signer::address_of(account); + let handle = global(sender).compliance_key_rotation_events; + let msg = ComplianceKeyRotationEvent { + new_compliance_public_key: new_key, + time_rotated_seconds: DiemTimestamp::spec_now_seconds(), + }; + emits msg to handle; + } + + /// Return the human-readable name for the VASP account. + /// Aborts if `addr` does not have a `Credential` resource. + public fun human_name(addr: address): vector acquires Credential { + assert!(exists(addr), errors::not_published(ECREDENTIAL)); + *&borrow_global(addr).human_name + } + spec human_name { + pragma opaque; + include AbortsIfNoCredential; + ensures result == global(addr).human_name; + } + + /// Return the base URL for `addr`. + /// Aborts if `addr` does not have a `Credential` resource. + public fun base_url(addr: address): vector acquires Credential { + assert!(exists(addr), errors::not_published(ECREDENTIAL)); + *&borrow_global(addr).base_url + } + spec base_url { + pragma opaque; + include AbortsIfNoCredential; + ensures result == global(addr).base_url; + } + /// Spec version of `Self::base_url`. + spec fun spec_base_url(addr: address): vector { + global(addr).base_url + } + + /// Return the compliance public key for `addr`. + /// Aborts if `addr` does not have a `Credential` resource. + public fun compliance_public_key(addr: address): vector acquires Credential { + assert!(exists(addr), errors::not_published(ECREDENTIAL)); + *&borrow_global(addr).compliance_public_key + } + spec compliance_public_key { + pragma opaque; + include AbortsIfNoCredential; + ensures result == spec_compliance_public_key(addr); + } + /// Spec version of `Self::compliance_public_key`. + spec fun spec_compliance_public_key(addr: address): vector { + global(addr).compliance_public_key + } + + /// Return the expiration date `addr` + /// Aborts if `addr` does not have a `Credential` resource. + public fun expiration_date(addr: address): u64 acquires Credential { + assert!(exists(addr), errors::not_published(ECREDENTIAL)); + *&borrow_global(addr).expiration_date + } + spec expiration_date { + pragma opaque; + include AbortsIfNoCredential; + ensures result == global(addr).expiration_date; + } + + /////////////////////////////////////////////////////////////////////////// + // Dual attestation requirements and checking + /////////////////////////////////////////////////////////////////////////// + + /// Return the address where the credentials for `addr` are stored + fun credential_address(addr: address): address { + if (VASP::is_child(addr)) VASP::parent_address(addr) else addr + } + spec credential_address { + pragma opaque; + aborts_if false; + ensures result == spec_credential_address(addr); + } + spec fun spec_credential_address(addr: address): address { + if (VASP::is_child(addr)) { + VASP::spec_parent_address(addr) + } else { + addr + } + } + + /// Helper which returns true if dual attestion is required for a deposit. + fun dual_attestation_required( + payer: address, payee: address, deposit_value: u64 + ): bool acquires Limit { + // travel rule applies for payments over a limit + let travel_rule_limit_microdiem = get_cur_microdiem_limit(); + let approx_xdx_microdiem_value = Diem::approx_xdx_for_value(deposit_value); + let above_limit = approx_xdx_microdiem_value >= travel_rule_limit_microdiem; + if (!above_limit) { + return false + }; + // self-deposits never require dual attestation + if (payer == payee) { + return false + }; + // dual attestation is required if the amount is above the limit AND between distinct + // VASPs + VASP::is_vasp(payer) && VASP::is_vasp(payee) && + VASP::parent_address(payer) != VASP::parent_address(payee) + } + spec dual_attestation_required { + pragma opaque; + include DualAttestationRequiredAbortsIf; + ensures result == spec_dual_attestation_required(payer, payee, deposit_value); + } + spec schema DualAttestationRequiredAbortsIf { + deposit_value: num; + include Diem::ApproxXdmForValueAbortsIf{from_value: deposit_value}; + aborts_if !spec_is_published() with errors::NOT_PUBLISHED; + } + spec fun spec_is_inter_vasp(payer: address, payee: address): bool { + VASP::is_vasp(payer) && VASP::is_vasp(payee) + && VASP::spec_parent_address(payer) != VASP::spec_parent_address(payee) + } + /// Helper functions which simulates `Self::dual_attestation_required`. + spec fun spec_dual_attestation_required( + payer: address, payee: address, deposit_value: u64 + ): bool { + Diem::spec_approx_xdx_for_value(deposit_value) + >= spec_get_cur_microdiem_limit() && + payer != payee && + spec_is_inter_vasp(payer, payee) + } + + /// Helper to construct a message for dual attestation. + /// Message is `metadata` | `payer` | `amount` | `DOMAIN_SEPARATOR`. + fun dual_attestation_message( + payer: address, metadata: vector, deposit_value: u64 + ): vector { + let message = metadata; + vector::append(&mut message, bcs::to_bytes(&payer)); + vector::append(&mut message, bcs::to_bytes(&deposit_value)); + vector::append(&mut message, DOMAIN_SEPARATOR); + message + } + spec dual_attestation_message { + /// Abstract from construction of message for the prover. Concatenation of results from `BCS::to_bytes` + /// are difficult to reason about, so we avoid doing it. This is possible because the actual value of this + /// message is not important for the verification problem, as long as the prover considers both + /// messages which fail verification and which do not. + pragma opaque; + aborts_if false; + ensures [abstract] result == spec_dual_attestation_message(payer, metadata, deposit_value); + } + /// Uninterpreted function for `Self::dual_attestation_message`. The actual value does not matter for + /// the verification of callers. + spec fun spec_dual_attestation_message(payer: address, metadata: vector, deposit_value: u64): vector; + + /// Helper function to check validity of a signature when dual attestion is required. + fun assert_signature_is_valid( + payer: address, + payee: address, + metadata_signature: vector, + metadata: vector, + deposit_value: u64 + ) acquires Credential { + // sanity check of signature validity + assert!( + vector::length(&metadata_signature) == 64, + errors::invalid_argument(EMALFORMED_METADATA_SIGNATURE) + ); + // sanity check of payee compliance key validity + let payee_compliance_key = compliance_public_key(credential_address(payee)); + assert!( + !vector::is_empty(&payee_compliance_key), + errors::invalid_state(EPAYEE_COMPLIANCE_KEY_NOT_SET) + ); + // sanity check of payee base URL validity + let payee_base_url = base_url(credential_address(payee)); + assert!( + !vector::is_empty(&payee_base_url), + errors::invalid_state(EPAYEE_BASE_URL_NOT_SET) + ); + // cryptographic check of signature validity + let message = dual_attestation_message(payer, metadata, deposit_value); + assert!( + Signature::ed25519_verify(metadata_signature, payee_compliance_key, message), + errors::invalid_argument(EINVALID_METADATA_SIGNATURE), + ); + } + spec assert_signature_is_valid { + pragma opaque = true; + include AssertSignatureValidAbortsIf; + } + spec schema AssertSignatureValidAbortsIf { + payer: address; + payee: address; + metadata_signature: vector; + metadata: vector; + deposit_value: u64; + include AbortsIfNoCredential{addr: spec_credential_address(payee)}; + aborts_if vector::is_empty(spec_compliance_public_key(spec_credential_address(payee))) with errors::INVALID_STATE; + aborts_if vector::is_empty(spec_base_url(spec_credential_address(payee))) with errors::INVALID_STATE; + aborts_if !spec_signature_is_valid(payer, payee, metadata_signature, metadata, deposit_value) + with errors::INVALID_ARGUMENT; + } + + /// Returns true if signature is valid. + spec fun spec_signature_is_valid( + payer: address, + payee: address, + metadata_signature: vector, + metadata: vector, + deposit_value: u64 + ): bool { + let payee_compliance_key = spec_compliance_public_key(spec_credential_address(payee)); + len(metadata_signature) == 64 && + !vector::is_empty(payee_compliance_key) && + Signature::ed25519_verify( + metadata_signature, + payee_compliance_key, + spec_dual_attestation_message(payer, metadata, deposit_value) + ) + } + + /// Public API for checking whether a payment of `value` coins of type `Currency` + /// from `payer` to `payee` has a valid dual attestation. This returns without aborting if + /// (1) dual attestation is not required for this payment, or + /// (2) dual attestation is required, and `metadata_signature` can be verified on the message + /// `metadata` | `payer` | `value` | `DOMAIN_SEPARATOR` using the `compliance_public_key` + /// published in `payee`'s `Credential` resource + /// It aborts with an appropriate error code if dual attestation is required, but one or more of + /// the conditions in (2) is not met. + public fun assert_payment_ok( + payer: address, + payee: address, + value: u64, + metadata: vector, + metadata_signature: vector + ) acquires Credential, Limit { + if (!vector::is_empty(&metadata_signature) || // allow opt-in dual attestation + dual_attestation_required(payer, payee, value) + ) { + assert_signature_is_valid(payer, payee, metadata_signature, metadata, value) + } + } + spec assert_payment_ok { + pragma opaque; + include AssertPaymentOkAbortsIf; + } + spec schema AssertPaymentOkAbortsIf { + payer: address; + payee: address; + value: u64; + metadata: vector; + metadata_signature: vector; + include len(metadata_signature) == 0 ==> DualAttestationRequiredAbortsIf{deposit_value: value}; + include (len(metadata_signature) != 0 || spec_dual_attestation_required(payer, payee, value)) + ==> AssertSignatureValidAbortsIf{deposit_value: value}; + } + + /////////////////////////////////////////////////////////////////////////// + // Creating and updating dual attestation limit + /////////////////////////////////////////////////////////////////////////// + + /// Travel rule limit set during genesis + public fun initialize(dr_account: &signer) { + DiemTimestamp::assert_genesis(); + CoreAddresses::assert_diem_root(dr_account); // operational constraint. + assert!(!exists(@DiemRoot), errors::already_published(ELIMIT)); + let initial_limit = (INITIAL_DUAL_ATTESTATION_LIMIT as u128) * (Diem::scaling_factor() as u128); + assert!(initial_limit <= MAX_U64, errors::limit_exceeded(ELIMIT)); + move_to( + dr_account, + Limit { + micro_xdx_limit: (initial_limit as u64) + } + ) + } + spec initialize { + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + aborts_if exists(@DiemRoot) with errors::ALREADY_PUBLISHED; + let initial_limit = INITIAL_DUAL_ATTESTATION_LIMIT * Diem::spec_scaling_factor(); + aborts_if initial_limit > MAX_U64 with errors::LIMIT_EXCEEDED; + include Diem::AbortsIfNoCurrency; // for scaling_factor. + ensures global(@DiemRoot).micro_xdx_limit == initial_limit; + } + + /// Return the current dual attestation limit in microdiem + public fun get_cur_microdiem_limit(): u64 acquires Limit { + assert!(exists(@DiemRoot), errors::not_published(ELIMIT)); + borrow_global(@DiemRoot).micro_xdx_limit + } + spec get_cur_microdiem_limit { + pragma opaque; + aborts_if !spec_is_published() with errors::NOT_PUBLISHED; + ensures result == spec_get_cur_microdiem_limit(); + } + + /// Set the dual attestation limit to `micro_diem_limit`. + /// Aborts if `tc_account` does not have the TreasuryCompliance role + public fun set_microdiem_limit(tc_account: &signer, micro_xdx_limit: u64) acquires Limit { + Roles::assert_treasury_compliance(tc_account); + assert!(exists(@DiemRoot), errors::not_published(ELIMIT)); + borrow_global_mut(@DiemRoot).micro_xdx_limit = micro_xdx_limit; + } + spec set_microdiem_limit { + /// Must abort if the signer does not have the TreasuryCompliance role [[H6]][PERMISSION]. + /// The permission UpdateDualAttestationLimit is granted to TreasuryCompliance. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + + aborts_if !spec_is_published() with errors::NOT_PUBLISHED; + ensures global(@DiemRoot).micro_xdx_limit == micro_xdx_limit; + } + + // **************************** SPECIFICATION ******************************** + spec module {} // switch documentation context back to module level + + /// # Initialization + + /// The Limit resource should be published after genesis + spec module { + invariant [suspendable] DiemTimestamp::is_operating() ==> spec_is_published(); + } + + /// # Helper Functions + spec module { + /// Helper function to determine whether the Limit is published. + fun spec_is_published(): bool { + exists(@DiemRoot) + } + + /// Mirrors `Self::get_cur_microdiem_limit`. + fun spec_get_cur_microdiem_limit(): u64 { + global(@DiemRoot).micro_xdx_limit + } + } + + /// # Access Control + spec module { + /// Only TreasuryCompliance can change the limit [[H6]][PERMISSION]. + invariant update forall a: address where old(exists(@DiemRoot)): + spec_get_cur_microdiem_limit() != old(spec_get_cur_microdiem_limit()) + ==> Roles::spec_signed_by_treasury_compliance_role(); + + /// The permission "RotateDualAttestationInfo(addr)" is only granted to ParentVASP or DD [[H17]][PERMISSION]. + /// "Credential" resources are only published under ParentVASP or DD accounts. + invariant forall addr1: address: + spec_has_credential(addr1) ==> + (Roles::spec_has_parent_VASP_role_addr(addr1) || + Roles::spec_has_designated_dealer_role_addr(addr1)); + + /// Only the one who owns Credential can rotate the dual attenstation info [[H17]][PERMISSION]. + invariant update forall a: address where old(spec_has_credential(a)): + global(a).compliance_public_key != old(global(a).compliance_public_key) + ==> signer::is_txn_signer_addr(a); + + invariant update forall a: address where old(spec_has_credential(a)): + global(a).base_url != old(global(a).base_url) + ==> signer::is_txn_signer_addr(a); + + /// The permission "RotateDualAttestationInfo(addr)" is not transferred [[J17]][PERMISSION]. + /// resource struct `Credential` is persistent. + invariant update forall a: address: + old(spec_has_credential(a)) ==> spec_has_credential(a); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Genesis.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Genesis.move new file mode 100644 index 000000000..d046a23e5 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Genesis.move @@ -0,0 +1,251 @@ +/// The `Genesis` module defines the Move initialization entry point of the Diem framework +/// when executing from a fresh state. +/// +/// > TODO: Currently there are a few additional functions called from Rust during genesis. +/// > Document which these are and in which order they are called. +module DiemFramework::Genesis { + use DiemFramework::AccountFreezing; + use DiemFramework::ChainId; + use DiemFramework::XUS; + use DiemFramework::DualAttestation; + use DiemFramework::XDX; + use DiemFramework::Diem; + use DiemFramework::DiemAccount; + use DiemFramework::DiemBlock; + use DiemFramework::DiemConfig; + use DiemFramework::DiemConsensusConfig; + use DiemFramework::DiemSystem; + use DiemFramework::DiemTimestamp; + use DiemFramework::DiemTransactionPublishingOption; + use DiemFramework::DiemVersion; + use DiemFramework::TransactionFee; + use DiemFramework::DiemVMConfig; + use DiemFramework::ParallelExecutionConfig; + use DiemFramework::ValidatorConfig; + use DiemFramework::ValidatorOperatorConfig; + use std::signer; + use std::vector; + + /// Initializes the Diem framework. + fun initialize( + dr_account: signer, + tc_account: signer, + dr_auth_key: vector, + tc_auth_key: vector, + initial_script_allow_list: vector>, + is_open_module: bool, + instruction_schedule: vector, + native_schedule: vector, + chain_id: u8, + initial_diem_version: u64, + consensus_config: vector, + ) { + initialize_internal( + &dr_account, + &tc_account, + dr_auth_key, + tc_auth_key, + initial_script_allow_list, + is_open_module, + instruction_schedule, + native_schedule, + chain_id, + initial_diem_version, + consensus_config, + ) + } + + /// Initializes the Diem Framework. Internal so it can be used by both genesis code, and for testing purposes + fun initialize_internal( + dr_account: &signer, + tc_account: &signer, + dr_auth_key: vector, + tc_auth_key: vector, + initial_script_allow_list: vector>, + is_open_module: bool, + instruction_schedule: vector, + native_schedule: vector, + chain_id: u8, + initial_diem_version: u64, + consensus_config: vector, + ) { + DiemAccount::initialize(dr_account, x"00000000000000000000000000000000"); + + ChainId::initialize(dr_account, chain_id); + + // On-chain config setup + DiemConfig::initialize(dr_account); + + // Consensus config setup + DiemConsensusConfig::initialize(dr_account); + + // Parallel execution config setup + ParallelExecutionConfig::initialize_parallel_execution(dr_account); + + // Currency setup + Diem::initialize(dr_account); + + // Currency setup + XUS::initialize(dr_account, tc_account); + + XDX::initialize(dr_account, tc_account); + + AccountFreezing::initialize(dr_account); + TransactionFee::initialize(tc_account); + + DiemSystem::initialize_validator_set(dr_account); + DiemVersion::initialize(dr_account, initial_diem_version); + DualAttestation::initialize(dr_account); + DiemBlock::initialize_block_metadata(dr_account); + + // Rotate auth keys for DiemRoot and TreasuryCompliance accounts to the given + // values + let dr_rotate_key_cap = DiemAccount::extract_key_rotation_capability(dr_account); + DiemAccount::rotate_authentication_key(&dr_rotate_key_cap, dr_auth_key); + DiemAccount::restore_key_rotation_capability(dr_rotate_key_cap); + + let tc_rotate_key_cap = DiemAccount::extract_key_rotation_capability(tc_account); + DiemAccount::rotate_authentication_key(&tc_rotate_key_cap, tc_auth_key); + DiemAccount::restore_key_rotation_capability(tc_rotate_key_cap); + + DiemTransactionPublishingOption::initialize( + dr_account, + initial_script_allow_list, + is_open_module, + ); + + DiemVMConfig::initialize( + dr_account, + instruction_schedule, + native_schedule, + ); + + DiemConsensusConfig::set(dr_account, consensus_config); + + // After we have called this function, all invariants which are guarded by + // `DiemTimestamp::is_operating() ==> ...` will become active and a verification condition. + // See also discussion at function specification. + DiemTimestamp::set_time_has_started(dr_account); + } + + /// Sets up the initial validator set for the Diem network. + /// The validator "owner" accounts, their UTF-8 names, and their authentication + /// keys are encoded in the `owners`, `owner_names`, and `owner_auth_key` vectors. + /// Each validator signs consensus messages with the private key corresponding to the Ed25519 + /// public key in `consensus_pubkeys`. + /// Each validator owner has its operation delegated to an "operator" (which may be + /// the owner). The operators, their names, and their authentication keys are encoded + /// in the `operators`, `operator_names`, and `operator_auth_keys` vectors. + /// Finally, each validator must specify the network address + /// (see diem/types/src/network_address/mod.rs) for itself and its full nodes. + fun create_initialize_owners_operators( + dr_account: signer, + owners: vector, + owner_names: vector>, + owner_auth_keys: vector>, + consensus_pubkeys: vector>, + operators: vector, + operator_names: vector>, + operator_auth_keys: vector>, + validator_network_addresses: vector>, + full_node_network_addresses: vector>, + ) { + let num_owners = vector::length(&owners); + let num_owner_names = vector::length(&owner_names); + assert!(num_owners == num_owner_names, 0); + let num_owner_keys = vector::length(&owner_auth_keys); + assert!(num_owner_names == num_owner_keys, 0); + let num_operators = vector::length(&operators); + assert!(num_owner_keys == num_operators, 0); + let num_operator_names = vector::length(&operator_names); + assert!(num_operators == num_operator_names, 0); + let num_operator_keys = vector::length(&operator_auth_keys); + assert!(num_operator_names == num_operator_keys, 0); + let num_validator_network_addresses = vector::length(&validator_network_addresses); + assert!(num_operator_keys == num_validator_network_addresses, 0); + let num_full_node_network_addresses = vector::length(&full_node_network_addresses); + assert!(num_validator_network_addresses == num_full_node_network_addresses, 0); + + let i = 0; + let dummy_auth_key_prefix = x"00000000000000000000000000000000"; + while (i < num_owners) { + let owner = vector::borrow(&owners, i); + let owner_address = signer::address_of(owner); + let owner_name = *vector::borrow(&owner_names, i); + // create each validator account and rotate its auth key to the correct value + DiemAccount::create_validator_account( + &dr_account, owner_address, copy dummy_auth_key_prefix, owner_name + ); + + let owner_auth_key = *vector::borrow(&owner_auth_keys, i); + let rotation_cap = DiemAccount::extract_key_rotation_capability(owner); + DiemAccount::rotate_authentication_key(&rotation_cap, owner_auth_key); + DiemAccount::restore_key_rotation_capability(rotation_cap); + + let operator = vector::borrow(&operators, i); + let operator_address = signer::address_of(operator); + let operator_name = *vector::borrow(&operator_names, i); + // create the operator account + rotate its auth key if it does not already exist + if (!DiemAccount::exists_at(operator_address)) { + DiemAccount::create_validator_operator_account( + &dr_account, operator_address, copy dummy_auth_key_prefix, copy operator_name + ); + let operator_auth_key = *vector::borrow(&operator_auth_keys, i); + let rotation_cap = DiemAccount::extract_key_rotation_capability(operator); + DiemAccount::rotate_authentication_key(&rotation_cap, operator_auth_key); + DiemAccount::restore_key_rotation_capability(rotation_cap); + }; + // assign the operator to its validator + assert!(ValidatorOperatorConfig::get_human_name(operator_address) == operator_name, 0); + ValidatorConfig::set_operator(owner, operator_address); + + // use the operator account set up the validator config + let validator_network_address = *vector::borrow(&validator_network_addresses, i); + let full_node_network_address = *vector::borrow(&full_node_network_addresses, i); + let consensus_pubkey = *vector::borrow(&consensus_pubkeys, i); + ValidatorConfig::set_config( + operator, + owner_address, + consensus_pubkey, + validator_network_address, + full_node_network_address + ); + + // finally, add this validator to the validator set + DiemSystem::add_validator(&dr_account, owner_address); + + i = i + 1; + } + } + + /// For verification of genesis, the goal is to prove that all the invariants which + /// become active after the end of this function hold. This cannot be achieved with + /// modular verification as we do in regular continuous testing. Rather, this module must + /// be verified **together** with the module(s) which provides the invariant. + /// + /// > TODO: currently verifying this module together with modules providing invariants + /// > (see above) times out. This can likely be solved by making more of the initialize + /// > functions called by this function opaque, and prove the according invariants locally to + /// > each module. + spec initialize { + /// Assume that this is called in genesis state (no timestamp). + requires DiemTimestamp::is_genesis(); + } + + #[test_only] + public fun setup(dr_account: &signer, tc_account: &signer) { + initialize_internal( + dr_account, + tc_account, + x"0000000000000000000000000000000000000000000000000000000000000000", + x"0000000000000000000000000000000000000000000000000000000000000000", + vector::empty(), // not needed for unit tests + false, // not needed for unit tests + x"", // instruction_schedule not needed for unit tests + x"", // native schedule not needed for unit tests + 4u8, // TESTING chain ID + 0, + vector::empty(), + ) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/NetworkIdentity.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/NetworkIdentity.move new file mode 100644 index 000000000..74720bf71 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/NetworkIdentity.move @@ -0,0 +1,356 @@ +/// Module managing Diemnet NetworkIdentity +module DiemFramework::NetworkIdentity { + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::errors; + use std::event::{Self, EventHandle}; + use std::signer; + use std::vector; + + /// Holder for all `NetworkIdentity` in an account + struct NetworkIdentity has key { + identities: vector>, + } + spec NetworkIdentity { + include UniqueMembers> {members: identities}; + } + + struct NetworkIdentityEventHandle has key { + /// Event handle for `identities` rotation events + identity_change_events: EventHandle + } + + /// Message sent when there are updates to the `NetworkIdentity`. + struct NetworkIdentityChangeNotification has drop, store { + /// The address of the account that changed identities + account: address, + /// The new identities + identities: vector>, + /// The time at which the `identities` was rotated + time_rotated_seconds: u64, + } + + const MAX_ADDR_IDENTITIES: u64 = 100; + + // Error Codes + + /// Network ID doesn't exist when trying to get it + const ENETWORK_ID_DOESNT_EXIST: u64 = 0; + /// Limit exceeded on number of identities for an address + const ENETWORK_ID_LIMIT_EXCEEDED: u64 = 1; + /// No identities provided for changes + const ENETWORK_ID_NO_INPUT: u64 = 2; + /// Network identity event handle invalid + const ENETWORK_ID_EVENT_HANDLE_INVALID: u64 = 3; + + public fun initialize_network_identity_event_handle(tc_account: &signer) { + Roles::assert_treasury_compliance(tc_account); + assert!( + !exists(signer::address_of(tc_account)), + errors::already_published(ENETWORK_ID_EVENT_HANDLE_INVALID) + ); + let event_handle = NetworkIdentityEventHandle { + identity_change_events: event::new_event_handle(tc_account), + }; + move_to( + tc_account, + event_handle, + ); + } + + fun tc_network_identity_event_handle_exists(): bool { + exists(@TreasuryCompliance) + } + + /// Initialize `NetworkIdentity` with an empty list + fun initialize_network_identity(account: &signer) { + let identities = vector::empty>(); + move_to(account, NetworkIdentity { identities }); + } + spec initialize_network_identity { + let account_addr = signer::address_of(account); + modifies global(account_addr); + } + + /// Return the underlying `NetworkIdentity` bytes + public fun get(account_addr: address): vector> acquires NetworkIdentity { + assert!( + exists(account_addr), + errors::not_published(ENETWORK_ID_DOESNT_EXIST) + ); + *&borrow_global(account_addr).identities + } + spec get { + aborts_if !exists(account_addr) with errors::NOT_PUBLISHED; + ensures result == global(account_addr).identities; + } + + /// Update and create if not exist `NetworkIdentity` + public fun add_identities(account: &signer, to_add: vector>) acquires NetworkIdentity, NetworkIdentityEventHandle { + assert!(tc_network_identity_event_handle_exists(), errors::not_published(ENETWORK_ID_EVENT_HANDLE_INVALID)); + let num_to_add = vector::length(&to_add); + assert!(num_to_add > 0, errors::invalid_argument(ENETWORK_ID_NO_INPUT)); + + if (!exists(signer::address_of(account))) { + initialize_network_identity(account); + }; + let account_addr = signer::address_of(account); + let identity = borrow_global_mut(account_addr); + let identities = &mut identity.identities; + + assert!( + vector::length(identities) + num_to_add <= MAX_ADDR_IDENTITIES, + errors::limit_exceeded(ENETWORK_ID_LIMIT_EXCEEDED) + ); + + let has_change = add_members_internal(identities, &to_add); + if (has_change) { + event::emit_event( + &mut borrow_global_mut(@TreasuryCompliance).identity_change_events, + NetworkIdentityChangeNotification { + account: account_addr, + identities: *&identity.identities, + time_rotated_seconds: DiemTimestamp::now_seconds(), + } + ); + } + } + spec add_identities { + pragma verify=false; // TODO: due to timeout + let account_addr = signer::address_of(account); + let prior_identities = if (exists(account_addr)) { + global(account_addr).identities + } else { + vec() + }; + let has_change = (exists e in to_add: !contains(prior_identities, e)); + + let post handle = global(@TreasuryCompliance).identity_change_events; + let post msg = NetworkIdentityChangeNotification { + account: account_addr, + identities: global(account_addr).identities, + time_rotated_seconds: DiemTimestamp::spec_now_seconds(), + }; + + aborts_if !tc_network_identity_event_handle_exists() with errors::NOT_PUBLISHED; + aborts_if len(to_add) == 0 with errors::INVALID_ARGUMENT; + aborts_if len(prior_identities) + len(to_add) > MAX_U64; + aborts_if len(prior_identities) + len(to_add) > MAX_ADDR_IDENTITIES with errors::LIMIT_EXCEEDED; + include has_change ==> DiemTimestamp::AbortsIfNotOperating; + include AddMembersInternalEnsures> { + old_members: prior_identities, + new_members: global(account_addr).identities, + }; + modifies global(account_addr); + emits msg to handle if has_change; + } + + /// Remove `NetworkIdentity`, skipping if it doesn't exist + public fun remove_identities(account: &signer, to_remove: vector>) acquires NetworkIdentity, NetworkIdentityEventHandle { + assert!(tc_network_identity_event_handle_exists(), errors::not_published(ENETWORK_ID_EVENT_HANDLE_INVALID)); + let num_to_remove = vector::length(&to_remove); + assert!(num_to_remove > 0, errors::invalid_argument(ENETWORK_ID_NO_INPUT)); + assert!( + num_to_remove <= MAX_ADDR_IDENTITIES, + errors::limit_exceeded(ENETWORK_ID_LIMIT_EXCEEDED) + ); + + let account_addr = signer::address_of(account); + assert!( + exists(account_addr), + errors::not_published(ENETWORK_ID_DOESNT_EXIST) + ); + + let identity = borrow_global_mut(account_addr); + let identities = &mut identity.identities; + + let has_change = remove_members_internal(identities, &to_remove); + if (has_change) { + event::emit_event( + &mut borrow_global_mut(@TreasuryCompliance).identity_change_events, + NetworkIdentityChangeNotification { + account: account_addr, + identities: *&identity.identities, + time_rotated_seconds: DiemTimestamp::now_seconds(), + } + ); + }; + } + spec remove_identities { + let account_addr = signer::address_of(account); + let prior_identities = global(account_addr).identities; + let has_change = (exists e in to_remove: contains(prior_identities, e)); + + let post handle = global(@TreasuryCompliance).identity_change_events; + let post msg = NetworkIdentityChangeNotification { + account: account_addr, + identities: global(account_addr).identities, + time_rotated_seconds: DiemTimestamp::spec_now_seconds(), + }; + + aborts_if !tc_network_identity_event_handle_exists() with errors::NOT_PUBLISHED; + aborts_if len(to_remove) == 0 with errors::INVALID_ARGUMENT; + aborts_if len(to_remove) > MAX_ADDR_IDENTITIES with errors::LIMIT_EXCEEDED; + aborts_if !exists(account_addr) with errors::NOT_PUBLISHED; + include has_change ==> DiemTimestamp::AbortsIfNotOperating; + include RemoveMembersInternalEnsures> { + old_members: prior_identities, + new_members: global(account_addr).identities, + }; + modifies global(account_addr); + emits msg to handle if has_change; + } + + // ================================================================= + // Set operation simulation + + /// Add all elements that appear in `to_add` into `members`. + /// + /// The `members` argument is essentially a set simulated by a vector, hence + /// the uniqueness of its elements are guaranteed, before and after the bulk + /// insertion. The `to_add` argument, on the other hand, does not guarantee + /// to be a set and hence can have duplicated elements. + fun add_members_internal( + members: &mut vector, + to_add: &vector, + ): bool { + let num_to_add = vector::length(to_add); + let num_existing = vector::length(members); + + let i = 0; + while ({ + spec { + invariant i <= num_to_add; + // the set can never reduce in size + invariant len(members) >= len(old(members)); + // the current set maintains the uniqueness of the elements + invariant forall j in 0..len(members), k in 0..len(members): members[j] == members[k] ==> j == k; + // the left-split of the current set is exactly the same as the original set + invariant forall j in 0..len(old(members)): members[j] == old(members)[j]; + // all elements in the the right-split of the current set is from the `to_add` vector + invariant forall j in len(old(members))..len(members): contains(to_add[0..i], members[j]); + // the current set includes everything in `to_add` we have seen so far + invariant forall j in 0..i: contains(members, to_add[j]); + // having no new members means that all elements in the `to_add` vector we have seen so far are already + // in the existing set, and vice versa. + invariant len(members) == len(old(members)) <==> (forall j in 0..i: contains(old(members), to_add[j])); + }; + (i < num_to_add) + }) { + let entry = vector::borrow(to_add, i); + if (!vector::contains(members, entry)) { + vector::push_back(members, *entry); + }; + i = i + 1; + }; + + vector::length(members) > num_existing + } + spec add_members_internal { + pragma opaque; + pragma verify=false; // TODO: disabled due to the failure when using Z3 4.8.13. + // TODO(mengxu): this is to force the prover to honor the "opaque" pragma in the ignore opaque setting + ensures [concrete] true; + + aborts_if false; + include AddMembersInternalEnsures { + old_members: old(members), + new_members: members, + }; + // ensures that the `members` argument is and remains a set + include UniqueMembers; + // returns whether a new element is added to the set + ensures result == (exists e in to_add: !contains(old(members), e)); + } + spec schema AddMembersInternalEnsures { + old_members: vector; + new_members: vector; + to_add: vector; + // everything in the `to_add` vector must be in the updated set + ensures forall e in to_add: contains(new_members, e); + // everything in the old set must remain in the updated set + ensures forall e in old_members: contains(new_members, e); + // everything in the updated set must come from either the old set or the `to_add` vector + ensures forall e in new_members: (contains(old_members, e) || contains(to_add, e)); + } + + /// Remove all elements that appear in `to_remove` from `members`. + /// + /// The `members` argument is essentially a set simulated by a vector, hence + /// the uniqueness of its elements are guaranteed, before and after the bulk + /// removal. The `to_remove` argument, on the other hand, does not guarantee + /// to be a set and hence can have duplicated elements. + fun remove_members_internal( + members: &mut vector, + to_remove: &vector, + ): bool { + let num_existing = vector::length(members); + let num_to_remove = vector::length(to_remove); + + let i = 0; + while ({ + spec { + invariant i <= num_to_remove; + // the set can never grow in size + invariant len(members) <= len(old(members)); + // the current set maintains the uniqueness of the elements + invariant forall j in 0..len(members), k in 0..len(members): members[j] == members[k] ==> j == k; + // all elements in the the current set come from the original set + invariant forall j in 0..len(members): contains(old(members), members[j]); + // the current set never contains anything from the `to_remove` vector + invariant forall j in 0..i: !contains(members, to_remove[j]); + // the current set should never remove an element from the original set which is not in `to_remove` + invariant forall j in 0..len(old(members)): (contains(to_remove[0..i], old(members)[j]) || contains(members, old(members)[j])); + // having the same member means that all elements in the `to_remove` vector we have seen so far are not + // in the existing set, and vice versa. + invariant len(members) == len(old(members)) <==> (forall j in 0..i: !contains(old(members), to_remove[j])); + }; + (i < num_to_remove) + }) { + let entry = vector::borrow(to_remove, i); + let (exist, index) = vector::index_of(members, entry); + if (exist) { + vector::swap_remove(members, index); + }; + i = i + 1; + }; + + vector::length(members) < num_existing + } + spec remove_members_internal { + // TODO: due to the complexity of the loop invariants and the extensive use of quantifiers in the spec, this + // function takes significantly longer to verify (expect 200+ seconds). We will need to investigate ways to + // reduce the verification time for this function in the future. Until then, disable the verification for now. + pragma verify = false; + + pragma opaque; + // TODO(mengxu): this is to force the prover to honor the "opaque" pragma in the ignore opaque setting + ensures [concrete] true; + + aborts_if false; + include RemoveMembersInternalEnsures { + old_members: old(members), + new_members: members, + }; + // ensures that the `members` argument is and remains a set + include UniqueMembers; + // returns whether an element is removed from the set + ensures result == (exists e in to_remove: contains(old(members), e)); + } + spec schema RemoveMembersInternalEnsures { + old_members: vector; + new_members: vector; + to_remove: vector; + // everything in the `to_remove` vector must not be in the updated set + ensures forall e in to_remove: !contains(new_members, e); + // all members in the updated set must be in the original set + ensures forall e in new_members: contains(old_members, e); + // an element from the original set that is not in the `to_remove` must be in the updated set + ensures forall e in old_members: (contains(to_remove, e) || contains(new_members, e)); + } + + spec schema UniqueMembers { + members: vector; + invariant forall i in 0..len(members), j in 0..len(members): members[i] == members[j] ==> i == j; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ParallelExecutionConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ParallelExecutionConfig.move new file mode 100644 index 000000000..85453253d --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ParallelExecutionConfig.move @@ -0,0 +1,115 @@ +/// This module defines structs and methods to initialize VM configurations, +/// including different costs of running the VM. +module DiemFramework::ParallelExecutionConfig { + use DiemFramework::DiemConfig::{Self, DiemConfig}; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::option::{Self, Option}; + + /// The struct to hold the read/write set analysis result for the whole Diem Framework. + struct ParallelExecutionConfig has copy, drop, store { + /// Serialized analysis result for the Diem Framework. + /// If this payload is not None, DiemVM will use this config to execute transactions in parallel. + read_write_analysis_result: Option> + } + + /// Enable parallel execution functionality of DiemVM by setting the read_write_set analysis result. + public fun initialize_parallel_execution( + dr_account: &signer, + ) { + // The permission "UpdateVMConfig" is granted to DiemRoot [[H11]][PERMISSION]. + Roles::assert_diem_root(dr_account); + DiemConfig::publish_new_config( + dr_account, + ParallelExecutionConfig { + read_write_analysis_result: option::none(), + }, + ); + } + + public fun enable_parallel_execution_with_config( + dr_account: &signer, + read_write_inference_result: vector, + ) { + DiemTimestamp::assert_operating(); + Roles::assert_diem_root(dr_account); + DiemConfig::set(dr_account, ParallelExecutionConfig { + read_write_analysis_result: option::some(read_write_inference_result), + }); + } + + public fun disable_parallel_execution( + dr_account: &signer, + ) { + DiemTimestamp::assert_operating(); + Roles::assert_diem_root(dr_account); + DiemConfig::set(dr_account, ParallelExecutionConfig { + read_write_analysis_result: option::none(), + }); + } + + spec initialize_parallel_execution { + /// Must abort if the signer does not have the DiemRoot role [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + + include DiemConfig::PublishNewConfigAbortsIf; + include DiemConfig::PublishNewConfigEnsures { + payload: ParallelExecutionConfig { + read_write_analysis_result: option::none(), + }}; + } + + spec enable_parallel_execution_with_config { + include DiemTimestamp::AbortsIfNotOperating; + /// No one can update DiemVMConfig except for the Diem Root account [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include DiemConfig::SetAbortsIf{account: dr_account }; + ensures DiemConfig::spec_is_published(); + + // TODO: How to replace this assertion since we can't invoke Option::some here? + // ensures DiemConfig::get() == ParallelExecutionConfig { + // read_write_analysis_result: result, + // }; + + ensures old(DiemConfig::spec_has_config()) == DiemConfig::spec_has_config(); + } + + spec disable_parallel_execution { + include DiemTimestamp::AbortsIfNotOperating; + /// No one can update DiemVMConfig except for the Diem Root account [[H11]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include DiemConfig::SetAbortsIf{account: dr_account }; + ensures DiemConfig::spec_is_published(); + ensures DiemConfig::get() == ParallelExecutionConfig { + read_write_analysis_result: option::none(), + }; + ensures old(DiemConfig::spec_has_config()) == DiemConfig::spec_has_config(); + } + + + spec module { } // Switch documentation context to module level. + + /// # Access Control + + /// The permission "UpdateParallelExecutionConfig" is granted to DiemRoot [[H11]][PERMISSION]. + spec module { + invariant [suspendable] forall addr: address + where exists>(addr): addr == @DiemRoot; + + invariant update [suspendable] old(DiemConfig::spec_is_published()) + && DiemConfig::spec_is_published() + && old(DiemConfig::get()) != DiemConfig::get() + ==> Roles::spec_signed_by_diem_root_role(); + } + + // TODO: The following is the old style spec, which can removed later. + /// No one can update DiemVMConfig except for the Diem Root account [[H11]][PERMISSION]. + spec schema DiemVMConfigRemainsSame { + ensures old(DiemConfig::spec_is_published()) ==> + global>(@DiemRoot) == + old(global>(@DiemRoot)); + } + spec module { + apply DiemVMConfigRemainsSame to * except enable_parallel_execution_with_config, disable_parallel_execution; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/PaymentScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/PaymentScripts.move new file mode 100644 index 000000000..77208a935 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/PaymentScripts.move @@ -0,0 +1,187 @@ +/// This module holds all payment related script entrypoints in the Diem Framework. +/// Any account that can hold a balance can use the transaction scripts within this module. +module DiemFramework::PaymentScripts { + use DiemFramework::DiemAccount; + use DiemFramework::DualAttestation; + use std::signer; + + /// # Summary + /// Transfers a given number of coins in a specified currency from one account to another. + /// Transfers over a specified amount defined on-chain that are between two different VASPs, or + /// other accounts that have opted-in will be subject to on-chain checks to ensure the receiver has + /// agreed to receive the coins. This transaction can be sent by any account that can hold a + /// balance, and to any account that can hold a balance. Both accounts must hold balances in the + /// currency being transacted. + /// + /// # Technical Description + /// + /// Transfers `amount` coins of type `Currency` from `payer` to `payee` with (optional) associated + /// `metadata` and an (optional) `metadata_signature` on the message of the form + /// `metadata` | `Signer::address_of(payer)` | `amount` | `DualAttestation::DOMAIN_SEPARATOR`, that + /// has been signed by the `payee`'s private key associated with the `compliance_public_key` held in + /// the `payee`'s `DualAttestation::Credential`. Both the `Signer::address_of(payer)` and `amount` fields + /// in the `metadata_signature` must be BCS-encoded bytes, and `|` denotes concatenation. + /// The `metadata` and `metadata_signature` parameters are only required if `amount` >= + /// `DualAttestation::get_cur_microdiem_limit` XDX and `payer` and `payee` are distinct VASPs. + /// However, a transaction sender can opt in to dual attestation even when it is not required + /// (e.g., a DesignatedDealer -> VASP payment) by providing a non-empty `metadata_signature`. + /// Standardized `metadata` BCS format can be found in `diem_types::transaction::metadata::Metadata`. + /// + /// # Events + /// Successful execution of this script emits two events: + /// * A `DiemAccount::SentPaymentEvent` on `payer`'s `DiemAccount::DiemAccount` `sent_events` handle; and + /// * A `DiemAccount::ReceivedPaymentEvent` on `payee`'s `DiemAccount::DiemAccount` `received_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Currency` | Type | The Move type for the `Currency` being sent in this transaction. `Currency` must be an already-registered currency on-chain. | + /// | `payer` | `signer` | The signer of the sending account that coins are being transferred from. | + /// | `payee` | `address` | The address of the account the coins are being transferred to. | + /// | `metadata` | `vector` | Optional metadata about this payment. | + /// | `metadata_signature` | `vector` | Optional signature over `metadata` and payment information. See | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `DiemAccount::EPAYER_DOESNT_HOLD_CURRENCY` | `payer` doesn't hold a balance in `Currency`. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EINSUFFICIENT_BALANCE` | `amount` is greater than `payer`'s balance in `Currency`. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::ECOIN_DEPOSIT_IS_ZERO` | `amount` is zero. | + /// | `Errors::NOT_PUBLISHED` | `DiemAccount::EPAYEE_DOES_NOT_EXIST` | No account exists at the `payee` address. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EPAYEE_CANT_ACCEPT_CURRENCY_TYPE` | An account exists at `payee`, but it does not accept payments in `Currency`. | + /// | `Errors::INVALID_STATE` | `AccountFreezing::EACCOUNT_FROZEN` | The `payee` account is frozen. | + /// | `Errors::INVALID_ARGUMENT` | `DualAttestation::EMALFORMED_METADATA_SIGNATURE` | `metadata_signature` is not 64 bytes. | + /// | `Errors::INVALID_ARGUMENT` | `DualAttestation::EINVALID_METADATA_SIGNATURE` | `metadata_signature` does not verify on the against the `payee'`s `DualAttestation::Credential` `compliance_public_key` public key. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EWITHDRAWAL_EXCEEDS_LIMITS` | `payer` has exceeded its daily withdrawal limits for the backing coins of XDX. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EDEPOSIT_EXCEEDS_LIMITS` | `payee` has exceeded its daily deposit limits for XDX. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_child_vasp_account` + /// * `AccountCreationScripts::create_parent_vasp_account` + /// * `AccountAdministrationScripts::add_currency_to_account` + /// * `PaymentScripts::peer_to_peer_by_signers` + public entry fun peer_to_peer_with_metadata( + payer: signer, + payee: address, + amount: u64, + metadata: vector, + metadata_signature: vector + ) { + let payer_withdrawal_cap = DiemAccount::extract_withdraw_capability(&payer); + DiemAccount::pay_from( + &payer_withdrawal_cap, payee, amount, metadata, metadata_signature + ); + DiemAccount::restore_withdraw_capability(payer_withdrawal_cap); + } + + /// # Summary + /// Transfers a given number of coins in a specified currency from one account to another by multi-agent transaction. + /// Transfers over a specified amount defined on-chain that are between two different VASPs, or + /// other accounts that have opted-in will be subject to on-chain checks to ensure the receiver has + /// agreed to receive the coins. This transaction can be sent by any account that can hold a + /// balance, and to any account that can hold a balance. Both accounts must hold balances in the + /// currency being transacted. + /// + /// # Technical Description + /// + /// Transfers `amount` coins of type `Currency` from `payer` to `payee` with (optional) associated + /// `metadata`. + /// Dual attestation is not applied to this script as payee is also a signer of the transaction. + /// Standardized `metadata` BCS format can be found in `diem_types::transaction::metadata::Metadata`. + /// + /// # Events + /// Successful execution of this script emits two events: + /// * A `DiemAccount::SentPaymentEvent` on `payer`'s `DiemAccount::DiemAccount` `sent_events` handle; and + /// * A `DiemAccount::ReceivedPaymentEvent` on `payee`'s `DiemAccount::DiemAccount` `received_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Currency` | Type | The Move type for the `Currency` being sent in this transaction. `Currency` must be an already-registered currency on-chain. | + /// | `payer` | `signer` | The signer of the sending account that coins are being transferred from. | + /// | `payee` | `signer` | The signer of the receiving account that the coins are being transferred to. | + /// | `metadata` | `vector` | Optional metadata about this payment. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `DiemAccount::EPAYER_DOESNT_HOLD_CURRENCY` | `payer` doesn't hold a balance in `Currency`. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EINSUFFICIENT_BALANCE` | `amount` is greater than `payer`'s balance in `Currency`. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::ECOIN_DEPOSIT_IS_ZERO` | `amount` is zero. | + /// | `Errors::NOT_PUBLISHED` | `DiemAccount::EPAYEE_DOES_NOT_EXIST` | No account exists at the `payee` address. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EPAYEE_CANT_ACCEPT_CURRENCY_TYPE` | An account exists at `payee`, but it does not accept payments in `Currency`. | + /// | `Errors::INVALID_STATE` | `AccountFreezing::EACCOUNT_FROZEN` | The `payee` account is frozen. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EWITHDRAWAL_EXCEEDS_LIMITS` | `payer` has exceeded its daily withdrawal limits for the backing coins of XDX. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EDEPOSIT_EXCEEDS_LIMITS` | `payee` has exceeded its daily deposit limits for XDX. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_child_vasp_account` + /// * `AccountCreationScripts::create_parent_vasp_account` + /// * `AccountAdministrationScripts::add_currency_to_account` + /// * `PaymentScripts::peer_to_peer_with_metadata` + public entry fun peer_to_peer_by_signers( + payer: signer, + payee: signer, + amount: u64, + metadata: vector, + ) { + let payer_withdrawal_cap = DiemAccount::extract_withdraw_capability(&payer); + DiemAccount::pay_by_signers( + &payer_withdrawal_cap, &payee, amount, metadata + ); + DiemAccount::restore_withdraw_capability(payer_withdrawal_cap); + } + + spec peer_to_peer_with_metadata { + include PeerToPeer{payer_signer: payer}; + include DualAttestation::AssertPaymentOkAbortsIf{ + payer: signer::address_of(payer), + value: amount + }; + } + + spec peer_to_peer_by_signers { + include PeerToPeer{payer_signer: payer, payee: signer::address_of(payee)}; + } + + spec schema PeerToPeer { + use std::errors; + + payer_signer: signer; + payee: address; + amount: u64; + metadata: vector; + + include DiemAccount::TransactionChecks{sender: payer_signer}; // properties checked by the prologue. + let payer_addr = signer::address_of(payer_signer); + let cap = DiemAccount::spec_get_withdraw_cap(payer_addr); + include DiemAccount::ExtractWithdrawCapAbortsIf{sender_addr: payer_addr}; + include DiemAccount::PayFromAbortsIf{cap: cap}; + + /// The balances of payer and payee change by the correct amount. + ensures payer_addr != payee + ==> DiemAccount::balance(payer_addr) + == old(DiemAccount::balance(payer_addr)) - amount; + ensures payer_addr != payee + ==> DiemAccount::balance(payee) + == old(DiemAccount::balance(payee)) + amount; + ensures payer_addr == payee + ==> DiemAccount::balance(payee) + == old(DiemAccount::balance(payee)); + + aborts_with [check] + errors::NOT_PUBLISHED, + errors::INVALID_STATE, + errors::INVALID_ARGUMENT, + errors::LIMIT_EXCEEDED; + + include DiemAccount::PayFromEmits{cap: cap}; + + /// **Access Control:** + /// Both the payer and the payee must hold the balances of the Currency. Only Designated Dealers, + /// Parent VASPs, and Child VASPs can hold balances [[D1]][ROLE][[D2]][ROLE][[D3]][ROLE][[D4]][ROLE][[D5]][ROLE][[D6]][ROLE][[D7]][ROLE]. + aborts_if !exists>(payer_addr) with errors::NOT_PUBLISHED; + aborts_if !exists>(payee) with errors::INVALID_ARGUMENT; + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/README b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/README new file mode 100644 index 000000000..14cfd09fd --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/README @@ -0,0 +1 @@ +This folder will contain DPN-specific Move modules. diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/RecoveryAddress.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/RecoveryAddress.move new file mode 100644 index 000000000..67c47d818 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/RecoveryAddress.move @@ -0,0 +1,268 @@ +/// This module defines an account recovery mechanism that can be used by VASPs. +module DiemFramework::RecoveryAddress { + use DiemFramework::DiemAccount::{Self, KeyRotationCapability}; + use DiemFramework::VASP; + use std::errors; + use std::signer; + use std::vector; + + /// A resource that holds the `KeyRotationCapability`s for several accounts belonging to the + /// same VASP. A VASP account that delegates its `KeyRotationCapability` to + /// but also allows the account that stores the `RecoveryAddress` resource to rotate its + /// authentication key. + /// This is useful as an account recovery mechanism: VASP accounts can all delegate their + /// rotation capabilities to a single `RecoveryAddress` resource stored under address A. + /// The authentication key for A can be "buried in the mountain" and dug up only if the need to + /// recover one of accounts in `rotation_caps` arises. + struct RecoveryAddress has key { + rotation_caps: vector + } + + /// Only VASPs can create a recovery address + const ENOT_A_VASP: u64 = 0; + /// A cycle would have been created would be created + const EKEY_ROTATION_DEPENDENCY_CYCLE: u64 = 1; + /// The signer doesn't have the appropriate privileges to rotate the account's key + const ECANNOT_ROTATE_KEY: u64 = 2; + /// Only accounts belonging to the same VASP can delegate their key rotation capability + const EINVALID_KEY_ROTATION_DELEGATION: u64 = 3; + /// The account address couldn't be found in the account recovery resource + const EACCOUNT_NOT_RECOVERABLE: u64 = 4; + /// A `RecoveryAddress` resource was in an unexpected state + const ERECOVERY_ADDRESS: u64 = 5; + /// The maximum allowed number of keys have been registered with this recovery address. + const EMAX_KEYS_REGISTERED: u64 = 6; + + /// The maximum number of keys that can be registered with a single recovery address. + const MAX_REGISTERED_KEYS: u64 = 256; + + /// Extract the `KeyRotationCapability` for `recovery_account` and publish it in a + /// `RecoveryAddress` resource under `recovery_account`. + /// Aborts if `recovery_account` has delegated its `KeyRotationCapability`, already has a + /// `RecoveryAddress` resource, or is not a VASP. + public fun publish(recovery_account: &signer, rotation_cap: KeyRotationCapability) { + let addr = signer::address_of(recovery_account); + // Only VASPs can create a recovery address + assert!(VASP::is_vasp(addr), errors::invalid_argument(ENOT_A_VASP)); + // put the rotation capability for the recovery account itself in `rotation_caps`. This + // ensures two things: + // (1) It's not possible to get into a "recovery cycle" where A is the recovery account for + // B and B is the recovery account for A + // (2) rotation_caps is always nonempty + assert!( + *DiemAccount::key_rotation_capability_address(&rotation_cap) == addr, + errors::invalid_argument(EKEY_ROTATION_DEPENDENCY_CYCLE) + ); + assert!(!exists(addr), errors::already_published(ERECOVERY_ADDRESS)); + move_to( + recovery_account, + RecoveryAddress { rotation_caps: vector::singleton(rotation_cap) } + ) + } + spec publish { + include PublishAbortsIf; + include PublishEnsures; + } + spec schema PublishAbortsIf { + recovery_account: signer; + rotation_cap: KeyRotationCapability; + let addr = signer::address_of(recovery_account); + aborts_if !VASP::is_vasp(addr) with errors::INVALID_ARGUMENT; + aborts_if spec_is_recovery_address(addr) with errors::ALREADY_PUBLISHED; + aborts_if DiemAccount::key_rotation_capability_address(rotation_cap) != addr + with errors::INVALID_ARGUMENT; + } + spec schema PublishEnsures { + recovery_account: signer; + rotation_cap: KeyRotationCapability; + let addr = signer::address_of(recovery_account); + ensures spec_is_recovery_address(addr); + ensures len(spec_get_rotation_caps(addr)) == 1; + ensures spec_get_rotation_caps(addr)[0] == rotation_cap; + } + + /// Rotate the authentication key of `to_recover` to `new_key`. Can be invoked by either + /// `recovery_address` or `to_recover`. + /// Aborts if `recovery_address` does not have the `KeyRotationCapability` for `to_recover`. + public fun rotate_authentication_key( + account: &signer, + recovery_address: address, + to_recover: address, + new_key: vector + ) acquires RecoveryAddress { + // Check that `recovery_address` has a `RecoveryAddress` resource + assert!(exists(recovery_address), errors::not_published(ERECOVERY_ADDRESS)); + let sender = signer::address_of(account); + assert!( + // The original owner of a key rotation capability can rotate its own key + sender == to_recover || + // The owner of the `RecoveryAddress` resource can rotate any key + sender == recovery_address, + errors::invalid_argument(ECANNOT_ROTATE_KEY) + ); + + let caps = &borrow_global(recovery_address).rotation_caps; + let i = 0; + let len = vector::length(caps); + while ({ + spec { + invariant i <= len; + invariant forall j in 0..i: caps[j].account_address != to_recover; + }; + (i < len) + }) + { + let cap = vector::borrow(caps, i); + if (DiemAccount::key_rotation_capability_address(cap) == &to_recover) { + DiemAccount::rotate_authentication_key(cap, new_key); + return + }; + i = i + 1 + }; + spec { + assert i == len; + assert forall j in 0..len: caps[j].account_address != to_recover; + }; + // Couldn't find `to_recover` in the account recovery resource; abort + abort errors::invalid_argument(EACCOUNT_NOT_RECOVERABLE) + } + spec rotate_authentication_key { + include RotateAuthenticationKeyAbortsIf; + include RotateAuthenticationKeyEnsures; + } + spec schema RotateAuthenticationKeyAbortsIf { + account: signer; + recovery_address: address; + to_recover: address; + new_key: vector; + aborts_if !spec_is_recovery_address(recovery_address) with errors::NOT_PUBLISHED; + aborts_if !DiemAccount::exists_at(to_recover) with errors::NOT_PUBLISHED; + aborts_if len(new_key) != 32 with errors::INVALID_ARGUMENT; + aborts_if !spec_holds_key_rotation_cap_for(recovery_address, to_recover) with errors::INVALID_ARGUMENT; + aborts_if !(signer::address_of(account) == recovery_address + || signer::address_of(account) == to_recover) with errors::INVALID_ARGUMENT; + } + spec schema RotateAuthenticationKeyEnsures { + to_recover: address; + new_key: vector; + ensures DiemAccount::authentication_key(to_recover) == new_key; + } + + /// Add `to_recover` to the `RecoveryAddress` resource under `recovery_address`. + /// Aborts if `to_recover.address` and `recovery_address` belong to different VASPs, or if + /// `recovery_address` does not have a `RecoveryAddress` resource. + public fun add_rotation_capability(to_recover: KeyRotationCapability, recovery_address: address) + acquires RecoveryAddress { + // Check that `recovery_address` has a `RecoveryAddress` resource + assert!(exists(recovery_address), errors::not_published(ERECOVERY_ADDRESS)); + // Only accept the rotation capability if both accounts belong to the same VASP + let to_recover_address = *DiemAccount::key_rotation_capability_address(&to_recover); + assert!( + VASP::is_same_vasp(recovery_address, to_recover_address), + errors::invalid_argument(EINVALID_KEY_ROTATION_DELEGATION) + ); + + let recovery_caps = &mut borrow_global_mut(recovery_address).rotation_caps; + assert!( + vector::length(recovery_caps) < MAX_REGISTERED_KEYS, + errors::limit_exceeded(EMAX_KEYS_REGISTERED) + ); + + vector::push_back(recovery_caps, to_recover); + } + spec add_rotation_capability { + include AddRotationCapabilityAbortsIf; + include AddRotationCapabilityEnsures; + } + spec schema AddRotationCapabilityAbortsIf { + to_recover: KeyRotationCapability; + recovery_address: address; + aborts_if !spec_is_recovery_address(recovery_address) with errors::NOT_PUBLISHED; + aborts_if len(global(recovery_address).rotation_caps) >= MAX_REGISTERED_KEYS with errors::LIMIT_EXCEEDED; + let to_recover_address = DiemAccount::key_rotation_capability_address(to_recover); + aborts_if !VASP::spec_is_same_vasp(recovery_address, to_recover_address) with errors::INVALID_ARGUMENT; + } + spec schema AddRotationCapabilityEnsures { + to_recover: KeyRotationCapability; + recovery_address: address; + let post num_rotation_caps = len(spec_get_rotation_caps(recovery_address)); + ensures spec_get_rotation_caps(recovery_address)[num_rotation_caps - 1] == to_recover; + } + + // ****************** SPECIFICATIONS ******************* + spec module {} // switch documentation context back to module level + + + /// # Initialization + + spec module { + /// A RecoveryAddress has its own `KeyRotationCapability`. + invariant forall addr: address + where spec_is_recovery_address(addr): ( + len(spec_get_rotation_caps(addr)) > 0 && + spec_get_rotation_caps(addr)[0].account_address == addr + ); + } + + /// # Persistence of Resource + + spec module { + invariant update + forall addr: address: + old(spec_is_recovery_address(addr)) ==> spec_is_recovery_address(addr); + } + + /// # Persistence of KeyRotationCapability + + spec module { + /// `RecoveryAddress` persists + invariant update forall addr: address where old(exists(addr)): + exists(addr); + + /// If `recovery_addr` holds the `KeyRotationCapability` of `to_recovery_addr` + /// in the previous state, then it continues to hold the capability after the update. + invariant update + forall recovery_addr: address, to_recovery_addr: address + where old(spec_is_recovery_address(recovery_addr)): + old(spec_holds_key_rotation_cap_for(recovery_addr, to_recovery_addr)) + ==> spec_holds_key_rotation_cap_for(recovery_addr, to_recovery_addr); + } + + + /// # Consistency Between Resources and Roles + + spec module { + /// Only VASPs can hold `RecoverAddress` resources. + invariant forall addr: address + where spec_is_recovery_address(addr): VASP::is_vasp(addr); + } + + /// # Helper Functions + + spec module { + /// Returns true if `addr` is a recovery address. + fun spec_is_recovery_address(addr: address): bool + { + exists(addr) + } + + /// Returns all the `KeyRotationCapability`s held at `recovery_address`. + fun spec_get_rotation_caps(recovery_address: address): + vector + { + global(recovery_address).rotation_caps + } + + /// Returns true if `recovery_address` holds the + /// `KeyRotationCapability` for `addr`. + fun spec_holds_key_rotation_cap_for( + recovery_address: address, + addr: address): bool + { + exists i: u64 + where 0 <= i && i < len(spec_get_rotation_caps(recovery_address)): + spec_get_rotation_caps(recovery_address)[i].account_address == addr + } + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/RegisteredCurrencies.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/RegisteredCurrencies.move new file mode 100644 index 000000000..db2685786 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/RegisteredCurrencies.move @@ -0,0 +1,102 @@ +/// Module for registering currencies in Diem. Basically, this means adding a +/// string (vector) for the currency name to vector of names in DiemConfig. +module DiemFramework::RegisteredCurrencies { + use DiemFramework::DiemConfig; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::errors; + use std::vector; + + /// A DiemConfig config holding all of the currency codes for registered + /// currencies. The inner vector's are string representations of + /// currency names. + struct RegisteredCurrencies has copy, drop, store { + currency_codes: vector>, + } + + /// Attempted to add a currency code that is already in use + const ECURRENCY_CODE_ALREADY_TAKEN: u64 = 0; + + /// Initializes this module. Can only be called from genesis, with + /// a Diem root signer. + public fun initialize(dr_account: &signer) { + DiemTimestamp::assert_genesis(); + Roles::assert_diem_root(dr_account); + DiemConfig::publish_new_config( + dr_account, + RegisteredCurrencies { currency_codes: vector::empty() } + ); + } + spec initialize { + include InitializeAbortsIf; + include InitializeEnsures; + } + + spec schema InitializeAbortsIf { + dr_account: signer; + include DiemTimestamp::AbortsIfNotGenesis; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include DiemConfig::PublishNewConfigAbortsIf; + } + spec schema InitializeEnsures { + include DiemConfig::PublishNewConfigEnsures{ + payload: RegisteredCurrencies { currency_codes: vector::empty() } + }; + ensures len(get_currency_codes()) == 0; + } + + /// Adds a new currency code. The currency code must not yet exist. + public fun add_currency_code( + dr_account: &signer, + currency_code: vector, + ) { + let config = DiemConfig::get(); + assert!( + !vector::contains(&config.currency_codes, ¤cy_code), + errors::invalid_argument(ECURRENCY_CODE_ALREADY_TAKEN) + ); + vector::push_back(&mut config.currency_codes, currency_code); + DiemConfig::set(dr_account, config); + } + spec add_currency_code { + include AddCurrencyCodeAbortsIf; + include AddCurrencyCodeEnsures; + } + spec schema AddCurrencyCodeAbortsIf { + dr_account: &signer; + currency_code: vector; + include DiemConfig::SetAbortsIf{ account: dr_account }; + /// The same currency code can be only added once. + aborts_if contains( + DiemConfig::get().currency_codes, + currency_code + ) with errors::INVALID_ARGUMENT; + } + spec schema AddCurrencyCodeEnsures { + currency_code: vector; + // The resulting currency_codes is the one before this function is called, with the new one added to the end. + ensures vector::eq_push_back(get_currency_codes(), old(get_currency_codes()), currency_code); + include DiemConfig::SetEnsures {payload: DiemConfig::get()}; + } + + // ================================================================= + // Module Specification + + spec module {} // switch documentation context back to module level + + /// # Initialization + + spec module { + /// Global invariant that currency config is always available after genesis. + invariant [suspendable] DiemTimestamp::is_operating() ==> DiemConfig::spec_is_published(); + } + + /// # Helper Functions + + spec module { + /// Helper to get the currency code vector. + fun get_currency_codes(): vector> { + DiemConfig::get().currency_codes + } + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Roles.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Roles.move new file mode 100644 index 000000000..97fc003e9 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Roles.move @@ -0,0 +1,610 @@ +/// This module defines role-based access control for the Diem framework. +/// +/// Roles are associated with accounts and govern what operations are permitted by those accounts. A role +/// is typically asserted on function entry using a statement like `Self::assert_diem_root(account)`. This +/// module provides multiple assertion functions like this one, as well as the functions to setup roles. +/// +/// For a conceptual discussion of roles, see the [DIP-2 document][ACCESS_CONTROL]. +module DiemFramework::Roles { + use DiemFramework::CoreAddresses; + use DiemFramework::DiemTimestamp; + use std::errors; + use std::signer; + friend DiemFramework::DiemAccount; + + #[test_only] + friend DiemFramework::RolesTests; + #[test_only] + friend DiemFramework::ValidatorOperatorConfigTests; + #[test_only] + friend DiemFramework::ValidatorConfigTests; + #[test_only] + friend DiemFramework::AccountLimitsTests; + + /// A `RoleId` resource was in an unexpected state + const EROLE_ID: u64 = 0; + /// The signer didn't have the required Diem Root role + const EDIEM_ROOT: u64 = 1; + /// The signer didn't have the required Treasury & Compliance role + const ETREASURY_COMPLIANCE: u64 = 2; + /// The signer didn't have the required Parent VASP role + const EPARENT_VASP: u64 = 3; + /// The signer didn't have the required ParentVASP or ChildVASP role + const EPARENT_VASP_OR_CHILD_VASP: u64 = 4; + /// The signer didn't have the required Parent VASP or Designated Dealer role + const EPARENT_VASP_OR_DESIGNATED_DEALER: u64 = 5; + /// The signer didn't have the required Designated Dealer role + const EDESIGNATED_DEALER: u64 = 6; + /// The signer didn't have the required Validator role + const EVALIDATOR: u64 = 7; + /// The signer didn't have the required Validator Operator role + const EVALIDATOR_OPERATOR: u64 = 8; + /// The signer didn't have the required Child VASP role + const ECHILD_VASP: u64 = 9; + + /////////////////////////////////////////////////////////////////////////// + // Role ID constants + /////////////////////////////////////////////////////////////////////////// + + const DIEM_ROOT_ROLE_ID: u64 = 0; + const TREASURY_COMPLIANCE_ROLE_ID: u64 = 1; + const DESIGNATED_DEALER_ROLE_ID: u64 = 2; + const VALIDATOR_ROLE_ID: u64 = 3; + const VALIDATOR_OPERATOR_ROLE_ID: u64 = 4; + const PARENT_VASP_ROLE_ID: u64 = 5; + const CHILD_VASP_ROLE_ID: u64 = 6; + + /// The roleId contains the role id for the account. This is only moved + /// to an account as a top-level resource, and is otherwise immovable. + struct RoleId has key { + role_id: u64, + } + + // ============= + // Role Granting + + /// Publishes diem root role. Granted only in genesis. + public(friend) fun grant_diem_root_role( + dr_account: &signer, + ) { + DiemTimestamp::assert_genesis(); + // Checks actual Diem root because Diem root role is not set + // until next line of code. + CoreAddresses::assert_diem_root(dr_account); + // Grant the role to the diem root account + grant_role(dr_account, DIEM_ROOT_ROLE_ID); + } + spec grant_diem_root_role { + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotDiemRoot{account: dr_account}; + include GrantRole{addr: signer::address_of(dr_account), role_id: DIEM_ROOT_ROLE_ID}; + } + + /// Publishes treasury compliance role. Granted only in genesis. + public(friend) fun grant_treasury_compliance_role( + treasury_compliance_account: &signer, + dr_account: &signer, + ) acquires RoleId { + DiemTimestamp::assert_genesis(); + CoreAddresses::assert_treasury_compliance(treasury_compliance_account); + assert_diem_root(dr_account); + // Grant the TC role to the treasury_compliance_account + grant_role(treasury_compliance_account, TREASURY_COMPLIANCE_ROLE_ID); + } + spec grant_treasury_compliance_role { + include DiemTimestamp::AbortsIfNotGenesis; + include CoreAddresses::AbortsIfNotTreasuryCompliance{account: treasury_compliance_account}; + include AbortsIfNotDiemRoot{account: dr_account}; + include GrantRole{addr: signer::address_of(treasury_compliance_account), role_id: TREASURY_COMPLIANCE_ROLE_ID}; + } + + /// Publishes a DesignatedDealer `RoleId` under `new_account`. + /// The `creating_account` must be treasury compliance. + public(friend) fun new_designated_dealer_role( + creating_account: &signer, + new_account: &signer, + ) acquires RoleId { + assert_treasury_compliance(creating_account); + grant_role(new_account, DESIGNATED_DEALER_ROLE_ID); + } + spec new_designated_dealer_role { + include AbortsIfNotTreasuryCompliance{account: creating_account}; + include GrantRole{addr: signer::address_of(new_account), role_id: DESIGNATED_DEALER_ROLE_ID}; + } + + /// Publish a Validator `RoleId` under `new_account`. + /// The `creating_account` must be diem root. + public(friend) fun new_validator_role( + creating_account: &signer, + new_account: &signer + ) acquires RoleId { + assert_diem_root(creating_account); + grant_role(new_account, VALIDATOR_ROLE_ID); + } + spec new_validator_role { + include AbortsIfNotDiemRoot{account: creating_account}; + include GrantRole{addr: signer::address_of(new_account), role_id: VALIDATOR_ROLE_ID}; + } + + /// Publish a ValidatorOperator `RoleId` under `new_account`. + /// The `creating_account` must be DiemRoot + public(friend) fun new_validator_operator_role( + creating_account: &signer, + new_account: &signer, + ) acquires RoleId { + assert_diem_root(creating_account); + grant_role(new_account, VALIDATOR_OPERATOR_ROLE_ID); + } + spec new_validator_operator_role { + include AbortsIfNotDiemRoot{account: creating_account}; + include GrantRole{addr: signer::address_of(new_account), role_id: VALIDATOR_OPERATOR_ROLE_ID}; + } + + /// Publish a ParentVASP `RoleId` under `new_account`. + /// The `creating_account` must be TreasuryCompliance + public(friend) fun new_parent_vasp_role( + creating_account: &signer, + new_account: &signer, + ) acquires RoleId { + assert_treasury_compliance(creating_account); + grant_role(new_account, PARENT_VASP_ROLE_ID); + } + spec new_parent_vasp_role { + include AbortsIfNotTreasuryCompliance{account: creating_account}; + include GrantRole{addr: signer::address_of(new_account), role_id: PARENT_VASP_ROLE_ID}; + } + + /// Publish a ChildVASP `RoleId` under `new_account`. + /// The `creating_account` must be a ParentVASP + public(friend) fun new_child_vasp_role( + creating_account: &signer, + new_account: &signer, + ) acquires RoleId { + assert_parent_vasp_role(creating_account); + grant_role(new_account, CHILD_VASP_ROLE_ID); + } + spec new_child_vasp_role { + include AbortsIfNotParentVasp{account: creating_account}; + include GrantRole{addr: signer::address_of(new_account), role_id: CHILD_VASP_ROLE_ID}; + } + + /// Helper function to grant a role. + fun grant_role(account: &signer, role_id: u64) { + assert!(!exists(signer::address_of(account)), errors::already_published(EROLE_ID)); + move_to(account, RoleId { role_id }); + } + spec grant_role { + pragma opaque; + include GrantRole{addr: signer::address_of(account)}; + let addr = signer::address_of(account); + // Requires to satisfy global invariants. + requires role_id == DIEM_ROOT_ROLE_ID ==> addr == @DiemRoot; + requires role_id == TREASURY_COMPLIANCE_ROLE_ID ==> addr == @TreasuryCompliance; + } + spec schema GrantRole { + addr: address; + role_id: num; + aborts_if exists(addr) with errors::ALREADY_PUBLISHED; + ensures exists(addr); + ensures global(addr).role_id == role_id; + modifies global(addr); + } + + // ============= + // Role Checking + + fun has_role(account: &signer, role_id: u64): bool acquires RoleId { + let addr = signer::address_of(account); + exists(addr) + && borrow_global(addr).role_id == role_id + } + + public fun has_diem_root_role(account: &signer): bool acquires RoleId { + has_role(account, DIEM_ROOT_ROLE_ID) + } + + public fun has_treasury_compliance_role(account: &signer): bool acquires RoleId { + has_role(account, TREASURY_COMPLIANCE_ROLE_ID) + } + + public fun has_designated_dealer_role(account: &signer): bool acquires RoleId { + has_role(account, DESIGNATED_DEALER_ROLE_ID) + } + + public fun has_validator_role(account: &signer): bool acquires RoleId { + has_role(account, VALIDATOR_ROLE_ID) + } + + public fun has_validator_operator_role(account: &signer): bool acquires RoleId { + has_role(account, VALIDATOR_OPERATOR_ROLE_ID) + } + + public fun has_parent_VASP_role(account: &signer): bool acquires RoleId { + has_role(account, PARENT_VASP_ROLE_ID) + } + + public fun has_child_VASP_role(account: &signer): bool acquires RoleId { + has_role(account, CHILD_VASP_ROLE_ID) + } + + public fun get_role_id(a: address): u64 acquires RoleId { + assert!(exists(a), errors::not_published(EROLE_ID)); + borrow_global(a).role_id + } + + /// Return true if `addr` is allowed to receive and send `Diem` for any T + public fun can_hold_balance(account: &signer): bool acquires RoleId { + // VASP accounts and designated_dealers can hold balances. + // Administrative accounts (`Validator`, `ValidatorOperator`, `TreasuryCompliance`, and + // `DiemRoot`) cannot. + has_parent_VASP_role(account) || + has_child_VASP_role(account) || + has_designated_dealer_role(account) + } + + // =============== + // Role Assertions + + /// Assert that the account is diem root. + public fun assert_diem_root(account: &signer) acquires RoleId { + CoreAddresses::assert_diem_root(account); + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(EROLE_ID)); + assert!(borrow_global(addr).role_id == DIEM_ROOT_ROLE_ID, errors::requires_role(EDIEM_ROOT)); + } + spec assert_diem_root { + pragma opaque; + include CoreAddresses::AbortsIfNotDiemRoot; + include AbortsIfNotDiemRoot; + } + + /// Assert that the account is treasury compliance. + public fun assert_treasury_compliance(account: &signer) acquires RoleId { + CoreAddresses::assert_treasury_compliance(account); + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(EROLE_ID)); + assert!( + borrow_global(addr).role_id == TREASURY_COMPLIANCE_ROLE_ID, + errors::requires_role(ETREASURY_COMPLIANCE) + ) + } + spec assert_treasury_compliance { + pragma opaque; + include AbortsIfNotTreasuryCompliance; + } + + /// Assert that the account has the parent vasp role. + public fun assert_parent_vasp_role(account: &signer) acquires RoleId { + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(EROLE_ID)); + assert!( + borrow_global(addr).role_id == PARENT_VASP_ROLE_ID, + errors::requires_role(EPARENT_VASP) + ) + } + spec assert_parent_vasp_role { + pragma opaque; + include AbortsIfNotParentVasp; + } + + /// Assert that the account has the child vasp role. + public fun assert_child_vasp_role(account: &signer) acquires RoleId { + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(EROLE_ID)); + assert!( + borrow_global(addr).role_id == CHILD_VASP_ROLE_ID, + errors::requires_role(ECHILD_VASP) + ) + } + spec assert_child_vasp_role { + pragma opaque; + include AbortsIfNotChildVasp{account: signer::address_of(account)}; + } + + + /// Assert that the account has the designated dealer role. + public fun assert_designated_dealer(account: &signer) acquires RoleId { + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(EROLE_ID)); + assert!( + borrow_global(addr).role_id == DESIGNATED_DEALER_ROLE_ID, + errors::requires_role(EDESIGNATED_DEALER) + ) + } + spec assert_designated_dealer { + pragma opaque; + include AbortsIfNotDesignatedDealer; + } + + /// Assert that the account has the validator role. + public fun assert_validator(validator_account: &signer) acquires RoleId { + let validator_addr = signer::address_of(validator_account); + assert!(exists(validator_addr), errors::not_published(EROLE_ID)); + assert!( + borrow_global(validator_addr).role_id == VALIDATOR_ROLE_ID, + errors::requires_role(EVALIDATOR) + ) + } + spec assert_validator { + pragma opaque; + include AbortsIfNotValidator{account: validator_account}; + } + + /// Assert that the account has the validator operator role. + public fun assert_validator_operator(validator_operator_account: &signer) acquires RoleId { + let validator_operator_addr = signer::address_of(validator_operator_account); + assert!(exists(validator_operator_addr), errors::not_published(EROLE_ID)); + assert!( + borrow_global(validator_operator_addr).role_id == VALIDATOR_OPERATOR_ROLE_ID, + errors::requires_role(EVALIDATOR_OPERATOR) + ) + } + spec assert_validator_operator { + pragma opaque; + include AbortsIfNotValidatorOperator{account: validator_operator_account}; + } + + /// Assert that the account has either the parent vasp or designated dealer role. + public fun assert_parent_vasp_or_designated_dealer(account: &signer) acquires RoleId { + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(EROLE_ID)); + let role_id = borrow_global(addr).role_id; + assert!( + role_id == PARENT_VASP_ROLE_ID || role_id == DESIGNATED_DEALER_ROLE_ID, + errors::requires_role(EPARENT_VASP_OR_DESIGNATED_DEALER) + ); + } + spec assert_parent_vasp_or_designated_dealer { + pragma opaque; + include AbortsIfNotParentVaspOrDesignatedDealer; + } + + public fun assert_parent_vasp_or_child_vasp(account: &signer) acquires RoleId { + let addr = signer::address_of(account); + assert!(exists(addr), errors::not_published(EROLE_ID)); + let role_id = borrow_global(addr).role_id; + assert!( + role_id == PARENT_VASP_ROLE_ID || role_id == CHILD_VASP_ROLE_ID, + errors::requires_role(EPARENT_VASP_OR_CHILD_VASP) + ); + } + spec assert_parent_vasp_or_child_vasp { + pragma opaque; + include AbortsIfNotParentVaspOrChildVasp; + } + + + //**************** Module Specification **************** + spec module {} // switch to module documentation context + + /// # Persistence of Roles + + /// Once an account at an address is granted a role it will remain an account role for all time. + spec module { + invariant update + forall addr: address where old(exists(addr)): + exists(addr) && old(global(addr).role_id) == global(addr).role_id; + } + + /// # Access Control + + /// In this section, the conditions from the [requirements for access control][ACCESS_CONTROL] are systematically + /// applied to the functions in this module. While some of those conditions have already been + /// included in individual function specifications, listing them here again gives additional + /// assurance that that all requirements are covered. + + spec module { + /// The DiemRoot role is only granted in genesis [[A1]][ROLE]. A new `RoleId` with `DIEM_ROOT_ROLE_ID` is only + /// published through `grant_diem_root_role` which aborts if it is not invoked in genesis. + apply ThisRoleIsNotNewlyPublished{this: DIEM_ROOT_ROLE_ID} to * except grant_diem_root_role, grant_role; + apply DiemTimestamp::AbortsIfNotGenesis to grant_diem_root_role; + + /// TreasuryCompliance role is only granted in genesis [[A2]][ROLE]. A new `RoleId` with `TREASURY_COMPLIANCE_ROLE_ID` is only + /// published through `grant_treasury_compliance_role` which aborts if it is not invoked in genesis. + apply ThisRoleIsNotNewlyPublished{this: TREASURY_COMPLIANCE_ROLE_ID} to * + except grant_treasury_compliance_role, grant_role; + apply DiemTimestamp::AbortsIfNotGenesis to grant_treasury_compliance_role; + + /// Validator roles are only granted by DiemRoot [[A3]][ROLE]. A new `RoleId` with `VALIDATOR_ROLE_ID` is only + /// published through `new_validator_role` which aborts if `creating_account` does not have the DiemRoot role. + apply ThisRoleIsNotNewlyPublished{this: VALIDATOR_ROLE_ID} to * except new_validator_role, grant_role; + apply AbortsIfNotDiemRoot{account: creating_account} to new_validator_role; + + /// ValidatorOperator roles are only granted by DiemRoot [[A4]][ROLE]. A new `RoleId` with `VALIDATOR_OPERATOR_ROLE_ID` is only + /// published through `new_validator_operator_role` which aborts if `creating_account` does not have the DiemRoot role. + apply ThisRoleIsNotNewlyPublished{this: VALIDATOR_OPERATOR_ROLE_ID} to * + except new_validator_operator_role, grant_role; + apply AbortsIfNotDiemRoot{account: creating_account} to new_validator_operator_role; + + /// DesignatedDealer roles are only granted by TreasuryCompliance [[A5]][ROLE]. A new `RoleId` with `DESIGNATED_DEALER_ROLE_ID()` + /// is only published through `new_designated_dealer_role` which aborts if `creating_account` does not have the + /// TreasuryCompliance role. + apply ThisRoleIsNotNewlyPublished{this: DESIGNATED_DEALER_ROLE_ID} to * + except new_designated_dealer_role, grant_role; + apply AbortsIfNotTreasuryCompliance{account: creating_account} to new_designated_dealer_role; + + /// ParentVASP roles are only granted by TreasuryCompliance [[A6]][ROLE]. A new `RoleId` with `PARENT_VASP_ROLE_ID()` is only + /// published through `new_parent_vasp_role` which aborts if `creating_account` does not have the TreasuryCompliance role. + apply ThisRoleIsNotNewlyPublished{this: PARENT_VASP_ROLE_ID} to * except new_parent_vasp_role, grant_role; + apply AbortsIfNotTreasuryCompliance{account: creating_account} to new_parent_vasp_role; + + /// ChildVASP roles are only granted by ParentVASP [[A7]][ROLE]. A new `RoleId` with `CHILD_VASP_ROLE_ID` is only + /// published through `new_child_vasp_role` which aborts if `creating_account` does not have the ParentVASP role. + apply ThisRoleIsNotNewlyPublished{this: CHILD_VASP_ROLE_ID} to * except new_child_vasp_role, grant_role; + apply AbortsIfNotParentVasp{account: creating_account} to new_child_vasp_role; + + /// The DiemRoot role is globally unique [[B1]][ROLE], and is published at DIEM_ROOT_ADDRESS [[C1]][ROLE]. + /// In other words, a `RoleId` with `DIEM_ROOT_ROLE_ID` uniquely exists at `DIEM_ROOT_ADDRESS`. + invariant forall addr: address where spec_has_diem_root_role_addr(addr): addr == @DiemRoot; + invariant [suspendable] + DiemTimestamp::is_operating() ==> spec_has_diem_root_role_addr(@DiemRoot); + + /// The TreasuryCompliance role is globally unique [[B2]][ROLE], and is published at TREASURY_COMPLIANCE_ADDRESS [[C2]][ROLE]. + /// In other words, a `RoleId` with `TREASURY_COMPLIANCE_ROLE_ID` uniquely exists at `TREASURY_COMPLIANCE_ADDRESS`. + invariant forall addr: address where spec_has_treasury_compliance_role_addr(addr): + addr == @TreasuryCompliance; + invariant [suspendable] + DiemTimestamp::is_operating() ==> spec_has_treasury_compliance_role_addr(@TreasuryCompliance); + + // TODO: These specs really just repeat what's in spec_can_hold_balance_addr. It's nice to + // be able to link to DIP-2, but can we do that with less verbose specs? + /// DiemRoot cannot have balances [[D1]][ROLE]. + invariant forall addr: address + where spec_has_diem_root_role_addr(addr): !spec_can_hold_balance_addr(addr); + + /// TreasuryCompliance cannot have balances [[D2]][ROLE]. + invariant forall addr: address + where spec_has_treasury_compliance_role_addr(addr): !spec_can_hold_balance_addr(addr); + + /// Validator cannot have balances [[D3]][ROLE]. + invariant forall addr: address + where spec_has_validator_role_addr(addr): !spec_can_hold_balance_addr(addr); + + /// ValidatorOperator cannot have balances [[D4]][ROLE]. + invariant forall addr: address + where spec_has_validator_operator_role_addr(addr): !spec_can_hold_balance_addr(addr); + + /// DesignatedDealer have balances [[D5]][ROLE]. + invariant forall addr: address + where spec_has_designated_dealer_role_addr(addr): spec_can_hold_balance_addr(addr); + + /// ParentVASP have balances [[D6]][ROLE]. + invariant forall addr: address + where spec_has_parent_VASP_role_addr(addr): spec_can_hold_balance_addr(addr); + + /// ChildVASP have balances [[D7]][ROLE]. + invariant forall addr: address + where spec_has_child_VASP_role_addr(addr): spec_can_hold_balance_addr(addr); + } + + /// # Helper Functions and Schemas + + spec module { + fun spec_get_role_id(addr: address): u64 { + global(addr).role_id + } + + fun spec_has_role_id_addr(addr: address, role_id: u64): bool { + exists(addr) && global(addr).role_id == role_id + } + + fun spec_has_diem_root_role_addr(addr: address): bool { + spec_has_role_id_addr(addr, DIEM_ROOT_ROLE_ID) + } + + fun spec_has_treasury_compliance_role_addr(addr: address): bool { + spec_has_role_id_addr(addr, TREASURY_COMPLIANCE_ROLE_ID) + } + + fun spec_has_designated_dealer_role_addr(addr: address): bool { + spec_has_role_id_addr(addr, DESIGNATED_DEALER_ROLE_ID) + } + + fun spec_has_validator_role_addr(addr: address): bool { + spec_has_role_id_addr(addr, VALIDATOR_ROLE_ID) + } + + fun spec_has_validator_operator_role_addr(addr: address): bool { + spec_has_role_id_addr(addr, VALIDATOR_OPERATOR_ROLE_ID) + } + + fun spec_has_parent_VASP_role_addr(addr: address): bool { + spec_has_role_id_addr(addr, PARENT_VASP_ROLE_ID) + } + + fun spec_has_child_VASP_role_addr(addr: address): bool { + spec_has_role_id_addr(addr, CHILD_VASP_ROLE_ID) + } + + fun spec_can_hold_balance_addr(addr: address): bool { + spec_has_parent_VASP_role_addr(addr) || + spec_has_child_VASP_role_addr(addr) || + spec_has_designated_dealer_role_addr(addr) + } + + fun spec_signed_by_treasury_compliance_role(): bool { + exists a: address: signer::is_txn_signer_addr(a) && spec_has_treasury_compliance_role_addr(a) + } + + fun spec_signed_by_diem_root_role(): bool { + exists a: address: signer::is_txn_signer_addr(a) && spec_has_diem_root_role_addr(a) + } + } + + spec schema ThisRoleIsNotNewlyPublished { + this: u64; + ensures forall addr: address where exists(addr) && global(addr).role_id == this: + old(exists(addr)) && old(global(addr).role_id) == this; + } + + spec schema AbortsIfNotDiemRoot { + account: signer; + include CoreAddresses::AbortsIfNotDiemRoot; + let addr = signer::address_of(account); + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + aborts_if global(addr).role_id != DIEM_ROOT_ROLE_ID with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotTreasuryCompliance { + account: signer; + include CoreAddresses::AbortsIfNotTreasuryCompliance; + let addr = signer::address_of(account); + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + aborts_if global(addr).role_id != TREASURY_COMPLIANCE_ROLE_ID with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotParentVasp { + account: signer; + let addr = signer::address_of(account); + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + aborts_if global(addr).role_id != PARENT_VASP_ROLE_ID with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotChildVasp { + account: address; + aborts_if !exists(account) with errors::NOT_PUBLISHED; + aborts_if global(account).role_id != CHILD_VASP_ROLE_ID with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotDesignatedDealer { + account: signer; + let addr = signer::address_of(account); + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + aborts_if global(addr).role_id != DESIGNATED_DEALER_ROLE_ID with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotParentVaspOrDesignatedDealer { + account: signer; + let addr = signer::address_of(account); + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + let role_id = global(addr).role_id; + aborts_if role_id != PARENT_VASP_ROLE_ID && role_id != DESIGNATED_DEALER_ROLE_ID + with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotParentVaspOrChildVasp { + account: signer; + let addr = signer::address_of(account); + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + let role_id = global(addr).role_id; + aborts_if role_id != PARENT_VASP_ROLE_ID && role_id != CHILD_VASP_ROLE_ID + with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotValidator { + account: signer; + let addr = signer::address_of(account); + //validator_addr: address; + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + aborts_if global(addr).role_id != VALIDATOR_ROLE_ID with errors::REQUIRES_ROLE; + } + + spec schema AbortsIfNotValidatorOperator { + account: signer; + let addr = signer::address_of(account); + //validator_operator_addr: address; + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + aborts_if global(addr).role_id != VALIDATOR_OPERATOR_ROLE_ID + with errors::REQUIRES_ROLE; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SharedEd25519PublicKey.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SharedEd25519PublicKey.move new file mode 100644 index 000000000..9127ccd11 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SharedEd25519PublicKey.move @@ -0,0 +1,149 @@ +/// Each address that holds a `SharedEd25519PublicKey` resource can rotate the public key stored in +/// this resource, but the account's authentication key will be updated in lockstep. This ensures +/// that the two keys always stay in sync. +module DiemFramework::SharedEd25519PublicKey { + use DiemFramework::Authenticator; + use DiemFramework::DiemAccount; + use DiemFramework::Signature; + use std::errors; + use std::signer; + + /// A resource that forces the account associated with `rotation_cap` to use a ed25519 + /// authentication key derived from `key` + struct SharedEd25519PublicKey has key { + /// 32 byte ed25519 public key + key: vector, + /// rotation capability for an account whose authentication key is always derived from `key` + rotation_cap: DiemAccount::KeyRotationCapability, + } + + /// The shared ed25519 public key is not valid ed25519 public key + const EMALFORMED_PUBLIC_KEY: u64 = 0; + /// A shared ed25519 public key resource was not in the required state + const ESHARED_KEY: u64 = 1; + + /// (1) Rotate the authentication key of the sender to `key` + /// (2) Publish a resource containing a 32-byte ed25519 public key and the rotation capability + /// of the sender under the `account`'s address. + /// Aborts if the sender already has a `SharedEd25519PublicKey` resource. + /// Aborts if the length of `new_public_key` is not 32. + public fun publish(account: &signer, key: vector) { + let t = SharedEd25519PublicKey { + key: x"", + rotation_cap: DiemAccount::extract_key_rotation_capability(account) + }; + rotate_key_(&mut t, key); + assert!(!exists_at(signer::address_of(account)), errors::already_published(ESHARED_KEY)); + move_to(account, t); + } + spec publish { + include PublishAbortsIf; + include PublishEnsures; + } + spec schema PublishAbortsIf { + account: signer; + key: vector; + let addr = signer::address_of(account); + include DiemAccount::ExtractKeyRotationCapabilityAbortsIf; + include RotateKey_AbortsIf { + shared_key: SharedEd25519PublicKey { + key: x"", + rotation_cap: DiemAccount::spec_get_key_rotation_cap(addr) + }, + new_public_key: key + }; + aborts_if exists_at(addr) with errors::ALREADY_PUBLISHED; + } + spec schema PublishEnsures { + account: signer; + key: vector; + let addr = signer::address_of(account); + + ensures exists_at(addr); + include RotateKey_Ensures { shared_key: global(addr), new_public_key: key}; + } + + fun rotate_key_(shared_key: &mut SharedEd25519PublicKey, new_public_key: vector) { + // Cryptographic check of public key validity + assert!( + Signature::ed25519_validate_pubkey(copy new_public_key), + errors::invalid_argument(EMALFORMED_PUBLIC_KEY) + ); + DiemAccount::rotate_authentication_key( + &shared_key.rotation_cap, + Authenticator::ed25519_authentication_key(copy new_public_key) + ); + shared_key.key = new_public_key; + } + spec rotate_key_ { + include RotateKey_AbortsIf; + include RotateKey_Ensures; + } + spec schema RotateKey_AbortsIf { + shared_key: SharedEd25519PublicKey; + new_public_key: vector; + aborts_if !Signature::ed25519_validate_pubkey(new_public_key) with errors::INVALID_ARGUMENT; + include DiemAccount::RotateAuthenticationKeyAbortsIf { + cap: shared_key.rotation_cap, + new_authentication_key: Authenticator::spec_ed25519_authentication_key(new_public_key) + }; + } + spec schema RotateKey_Ensures { + shared_key: SharedEd25519PublicKey; + new_public_key: vector; + ensures shared_key.key == new_public_key; + } + + /// (1) rotate the public key stored `account`'s `SharedEd25519PublicKey` resource to + /// `new_public_key` + /// (2) rotate the authentication key using the capability stored in the `account`'s + /// `SharedEd25519PublicKey` to a new value derived from `new_public_key` + /// Aborts if the sender does not have a `SharedEd25519PublicKey` resource. + /// Aborts if the length of `new_public_key` is not 32. + public fun rotate_key(account: &signer, new_public_key: vector) acquires SharedEd25519PublicKey { + let addr = signer::address_of(account); + assert!(exists_at(addr), errors::not_published(ESHARED_KEY)); + rotate_key_(borrow_global_mut(addr), new_public_key); + } + spec rotate_key { + include RotateKeyAbortsIf; + include RotateKeyEnsures; + } + spec schema RotateKeyAbortsIf { + account: signer; + new_public_key: vector; + let addr = signer::address_of(account); + aborts_if !exists_at(addr) with errors::NOT_PUBLISHED; + include RotateKey_AbortsIf {shared_key: global(addr)}; + } + spec schema RotateKeyEnsures { + account: signer; + new_public_key: vector; + let addr = signer::address_of(account); + include RotateKey_Ensures {shared_key: global(addr)}; + } + + /// Return the public key stored under `addr`. + /// Aborts if `addr` does not hold a `SharedEd25519PublicKey` resource. + public fun key(addr: address): vector acquires SharedEd25519PublicKey { + assert!(exists_at(addr), errors::not_published(ESHARED_KEY)); + *&borrow_global(addr).key + } + + /// Returns true if `addr` holds a `SharedEd25519PublicKey` resource. + public fun exists_at(addr: address): bool { + exists(addr) + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Persistence + spec module { + invariant update forall addr: address where old(exists(addr)): + exists(addr); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Signature.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Signature.move new file mode 100644 index 000000000..df6996b40 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/Signature.move @@ -0,0 +1,24 @@ +/// Contains functions for [ed25519](https://en.wikipedia.org/wiki/EdDSA) digital signatures. +module DiemFramework::Signature { + + /// Return `true` if the bytes in `public_key` can be parsed as a valid Ed25519 public key. + /// Returns `false` if `public_key` is not 32 bytes OR is 32 bytes, but does not pass + /// points-on-curve or small subgroup checks. See the Rust `diem_crypto::Ed25519PublicKey` type + /// for more details. + /// Does not abort. + native public fun ed25519_validate_pubkey(public_key: vector): bool; + + /// Return true if the Ed25519 `signature` on `message` verifies against the Ed25519 public key + /// `public_key`. + /// Returns `false` if: + /// - `signature` is not 64 bytes + /// - `public_key` is not 32 bytes + /// - `public_key` does not pass points-on-curve or small subgroup checks, + /// - `signature` and `public_key` are valid, but the signature on `message` does not verify. + /// Does not abort. + native public fun ed25519_verify( + signature: vector, + public_key: vector, + message: vector + ): bool; +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SlidingNonce.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SlidingNonce.move new file mode 100644 index 000000000..274602ae0 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SlidingNonce.move @@ -0,0 +1,296 @@ +/// Allows transactions to be executed out-of-order while ensuring that they are executed at most once. +/// Nonces are assigned to transactions off-chain by clients submitting the transactions. +/// It maintains a sliding window bitvector of 128 flags. A flag of 0 indicates that the transaction +/// with that nonce has not yet been executed. +/// When nonce X is recorded, all transactions with nonces lower then X-128 will abort. +module DiemFramework::SlidingNonce { + use std::signer; + use std::errors; + friend DiemFramework::DiemAccount; + + struct SlidingNonce has key { + /// Minimum nonce in sliding window. All transactions with smaller + /// nonces will be automatically rejected, since the window cannot + /// tell whether they have been executed or not. + min_nonce: u64, + /// Bit-vector of window of nonce values + nonce_mask: u128, + } + + /// The `SlidingNonce` resource is in an invalid state + const ESLIDING_NONCE: u64 = 0; + /// The nonce aborted because it's too old (nonce smaller than `min_nonce`) + const ENONCE_TOO_OLD: u64 = 1; + /// The nonce is too large - this protects against nonce exhaustion + const ENONCE_TOO_NEW: u64 = 2; + /// The nonce was already recorded previously + const ENONCE_ALREADY_RECORDED: u64 = 3; + /// The sliding nonce resource was already published + const ENONCE_ALREADY_PUBLISHED: u64 = 4; + + /// Size of SlidingNonce::nonce_mask in bits. + const NONCE_MASK_SIZE: u64 = 128; + + /// Calls `try_record_nonce` and aborts transaction if returned code is non-0 + public fun record_nonce_or_abort(account: &signer, seq_nonce: u64) acquires SlidingNonce { + let code = try_record_nonce(account, seq_nonce); + assert!(code == 0, errors::invalid_argument(code)); + } + + spec record_nonce_or_abort { + include RecordNonceAbortsIf; + } + + spec schema RecordNonceAbortsIf { + account: signer; + seq_nonce: u64; + aborts_if !exists(signer::address_of(account)) with errors::NOT_PUBLISHED; + aborts_if spec_try_record_nonce(account, seq_nonce) != 0 with errors::INVALID_ARGUMENT; + } + + /// # Explanation of the Algorithm + /// + /// We have an "infinite" bitvector. The `min_nonce` tells us the starting + /// index of the window. The window size is the size of the bitmask we can + /// represent in a 128-bit wide bitmap. The `seq_nonce` that is sent represents + /// setting a bit at index `seq_nonce` in this infinite bitvector. Because of + /// this, if the same `seq_nonce` is passed in multiple times, that bit will be + /// set, and we can signal an error. In order to represent + /// the `seq_nonce` the window we are looking at must be shifted so that + /// `seq_nonce` lies within that 128-bit window and, since the `min_nonce` + /// represents the left-hand-side of this window, it must be increased to be no + /// less than `seq_nonce - 128`. + /// + /// The process of shifting window will invalidate other transactions that + /// have a `seq_nonce` number that are to the "left" of this window (i.e., less + /// than `min_nonce`) since it cannot be represented in the current window, and the + /// window can only move forward and never backwards. + /// + /// In order to prevent shifting this window over too much at any one time, a + /// `jump_limit` is imposed. If a `seq_nonce` is provided that would cause the + /// `min_nonce` to need to be increased by more than the `jump_limit` this will + /// cause a failure. + /// + /// # Some Examples + /// + /// Let's say we start out with a clean `SlidingNonce` published under `account`, + /// this will look like this: + /// ``` + /// 000000000000000000...00000000000000000000000000000... + /// ^ ... ^ + /// |_____________...________________| + /// min_nonce = 0 min_nonce + NONCE_MASK_SIZE = 0 + 64 = 64 + /// ``` + /// + /// # Example 1: + /// + /// Let's see what happens when we call`SlidingNonce::try_record_nonce(account, 8)`: + /// + /// 1. Determine the bit position w.r.t. the current window: + /// ``` + /// bit_pos = 8 - min_nonce ~~~ 8 - 0 = 8 + /// ``` + /// 2. See if the bit position that was calculated is not within the current window: + /// ``` + /// bit_pos >= NONCE_MASK_SIZE ~~~ 8 >= 128 = FALSE + /// ``` + /// 3. `bit_pos` is in window, so set the 8'th bit in the window: + /// ``` + /// 000000010000000000...00000000000000000000000000000... + /// ^ ... ^ + /// |_____________...________________| + /// min_nonce = 0 min_nonce + NONCE_MASK_SIZE = 0 + 64 = 64 + /// ``` + /// + /// # Example 2: + /// + /// Let's see what happens when we call `SlidingNonce::try_record_nonce(account, 129)`: + /// + /// 1. Figure out the bit position w.r.t. the current window: + /// ``` + /// bit_pos = 129 - min_nonce ~~~ 129 - 0 = 129 + /// ``` + /// 2. See if bit position calculated is not within the current window starting at `min_nonce`: + /// ``` + /// bit_pos >= NONCE_MASK_SIZE ~~~ 129 >= 128 = TRUE + /// ``` + /// 3. `bit_pos` is outside of the current window. So we need to shift the window over. Now calculate the amount that + /// the window needs to be shifted over (i.e., the amount that `min_nonce` needs to be increased by) so that + /// `seq_nonce` lies within the `NONCE_MASK_SIZE` window starting at `min_nonce`. + /// 3a. Calculate the amount that the window needs to be shifted for `bit_pos` to lie within it: + /// ``` + /// shift = bit_pos - NONCE_MASK_SIZE + 1 ~~~ 129 - 128 + 1 = 2 + /// ``` + /// 3b. See if there is no overlap between the new window that we need to shift to and the old window: + /// ``` + /// shift >= NONCE_MASK_SIZE ~~~ 2 >= 128 = FALSE + /// ``` + /// 3c. Since there is an overlap between the new window that we need to shift to and the previous + /// window, shift the window over, but keep the current set bits in the overlapping part of the window: + /// ``` + /// nonce_mask = nonce_mask >> shift; min_nonce += shift; + /// ``` + /// 4. Now that the window has been shifted over so that the `seq_nonce` index lies within the new window we + /// recompute the `bit_pos` w.r.t. to it (recall `min_nonce` was updated): + /// ``` + /// bit_pos = seq - min_nonce ~~~ 129 - 2 = 127 + /// ``` + /// 5. We set the bit_pos position bit within the new window: + /// ``` + /// 00000001000000000000000...000000000000000000000000000000000000000000010... + /// ^ ... ^^ + /// | ... || + /// | ... new_set_bit| + /// |_______________...____________________________________________| + /// min_nonce = 2 min_nonce + NONCE_MASK_SIZE = 2 + 128 = 130 + /// ``` + /// + /// # Example 3: + /// + /// Let's see what happens when we call `SlidingNonce::try_record_nonce(account, 400)`: + /// + /// 1. Figure out the bit position w.r.t. the current window: + /// ``` + /// bit_pos = 400 - min_nonce ~~~ 400 - 2 = 398 + /// ``` + /// 2. See if bit position calculated is not within the current window: + /// ``` + /// bit_pos >= NONCE_MASK_SIZE ~~~ 398 >= 128 = TRUE + /// ``` + /// 3. `bit_pos` is out of the window. Now calculate the amount that + /// the window needs to be shifted over (i.e., that `min_nonce` needs to be incremented) so + /// `seq_nonce` lies within the `NONCE_MASK_SIZE` window starting at min_nonce. + /// 3a. Calculate the amount that the window needs to be shifted for `bit_pos` to lie within it: + /// ``` + /// shift = bit_pos - NONCE_MASK_SIZE + 1 ~~~ 398 - 128 + 1 = 271 + /// ``` + /// 3b. See if there is no overlap between the new window that we need to shift to and the old window: + /// ``` + /// shift >= NONCE_MASK_SIZE ~~~ 271 >= 128 = TRUE + /// ``` + /// 3c. Since there is no overlap between the new window that we need to shift to and the previous + /// window we zero out the bitmap, and update the `min_nonce` to start at the out-of-range `seq_nonce`: + /// ``` + /// nonce_mask = 0; min_nonce = seq_nonce + 1 - NONCE_MASK_SIZE = 273; + /// ``` + /// 4. Now that the window has been shifted over so that the `seq_nonce` index lies within the window we + /// recompute the bit_pos: + /// ``` + /// bit_pos = seq_nonce - min_nonce ~~~ 400 - 273 = 127 + /// ``` + /// 5. We set the bit_pos position bit within the new window: + /// ``` + /// ...00000001000000000000000...000000000000000000000000000000000000000000010... + /// ^ ... ^^ + /// | ... || + /// | ... new_set_bit| + /// |_______________...____________________________________________| + /// min_nonce = 273 min_nonce + NONCE_MASK_SIZE = 273 + 128 = 401 + /// ``` + /// Tries to record this nonce in the account. + /// Returns 0 if a nonce was recorded and non-0 otherwise + public fun try_record_nonce(account: &signer, seq_nonce: u64): u64 acquires SlidingNonce { + if (seq_nonce == 0) { + return 0 + }; + assert!(exists(signer::address_of(account)), errors::not_published(ESLIDING_NONCE)); + let t = borrow_global_mut(signer::address_of(account)); + // The `seq_nonce` is outside the current window to the "left" and is + // no longer valid since we can't shift the window back. + if (t.min_nonce > seq_nonce) { + return ENONCE_TOO_OLD + }; + // Don't allow giant leaps in nonce to protect against nonce exhaustion + // If we try to move a window by more than this amount, we will fail. + let jump_limit = 10000; + if (t.min_nonce + jump_limit <= seq_nonce) { + return ENONCE_TOO_NEW + }; + // Calculate The bit position in the window that will be set in our window + let bit_pos = seq_nonce - t.min_nonce; + + // See if the bit position that we want to set lies outside the current + // window that we have under the current `min_nonce`. + if (bit_pos >= NONCE_MASK_SIZE) { + // Determine how much we need to shift the current window over (to + // the "right") so that `bit_pos` lies within the new window. + let shift = (bit_pos - NONCE_MASK_SIZE + 1); + + // If we are shifting the window over by more than one window's width + // reset the bits in the window, and update the + // new start of the `min_nonce` so that `seq_nonce` is the + // right-most bit in the new window. + if(shift >= NONCE_MASK_SIZE) { + t.nonce_mask = 0; + t.min_nonce = seq_nonce + 1 - NONCE_MASK_SIZE; + } else { + // We are shifting the window over by less than a windows width, + // so we need to keep the current set bits in the window + t.nonce_mask = t.nonce_mask >> (shift as u8); + t.min_nonce = t.min_nonce + shift; + } + }; + // The window has been (possibly) shifted over so that `seq_nonce` lies + // within the window. Recompute the bit positition that needs to be set + // within the (possibly) new window. + let bit_pos = seq_nonce - t.min_nonce; + let set = 1u128 << (bit_pos as u8); + // The bit was already set, so return an error. + if (t.nonce_mask & set != 0) { + return ENONCE_ALREADY_RECORDED + }; + t.nonce_mask = t.nonce_mask | set; + 0 + } + + spec try_record_nonce { + /// It is currently assumed that this function raises no arithmetic overflow/underflow. + /// >Note: Verification is turned off. For verifying callers, this is effectively abstracted into a function + /// that returns arbitrary results because `spec_try_record_nonce` is uninterpreted. + pragma opaque, verify = false; + aborts_if !exists(signer::address_of(account)) with errors::NOT_PUBLISHED; + modifies global(signer::address_of(account)); + ensures result == spec_try_record_nonce(account, seq_nonce); + ensures exists(signer::address_of(account)); + } + + /// Specification version of `Self::try_record_nonce`. + spec fun spec_try_record_nonce(account: signer, seq_nonce: u64): u64; + + /// Publishes nonce resource for `account` + /// This is required before other functions in this module can be called for `account` + public(friend) fun publish(account: &signer) { + assert!(!exists(signer::address_of(account)), errors::already_published(ENONCE_ALREADY_PUBLISHED)); + move_to(account, SlidingNonce { min_nonce: 0, nonce_mask: 0 }); + } + spec publish { + pragma opaque; + modifies global(signer::address_of(account)); + aborts_if exists(signer::address_of(account)) with errors::ALREADY_PUBLISHED; + ensures exists(signer::address_of(account)); + ensures global(signer::address_of(account)).min_nonce == 0; + ensures global(signer::address_of(account)).nonce_mask == 0; + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + spec module { + use DiemFramework::DiemTimestamp; + + /// Sliding nonces are initialized at Diem root and treasury compliance addresses + invariant [suspendable] DiemTimestamp::is_operating() + ==> exists(@DiemRoot); + + invariant [suspendable] DiemTimestamp::is_operating() + ==> exists(@TreasuryCompliance); + + // In the current code, only Diem root and Treasury compliance have sliding nonces. + // That is a difficult cross-module invariant to prove (it depends on Genesis and + // DiemAccount). Additional modules could be added that call the publish functions + // in this module to publish sliding nonces on other accounts. Anyway, this property + // is probably not very important. + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SystemAdministrationScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SystemAdministrationScripts.move new file mode 100644 index 000000000..f185964a2 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/SystemAdministrationScripts.move @@ -0,0 +1,163 @@ +/// This module contains Diem Framework script functions to administer the +/// network outside of validators and validator operators. +module DiemFramework::SystemAdministrationScripts { + use DiemFramework::DiemConsensusConfig; + use DiemFramework::DiemVersion; + use DiemFramework::DiemVMConfig; + use DiemFramework::SlidingNonce; + + /// # Summary + /// Updates the Diem major version that is stored on-chain and is used by the VM. This + /// transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Updates the `DiemVersion` on-chain config and emits a `DiemConfig::NewEpochEvent` to trigger + /// a reconfiguration of the system. The `major` version that is passed in must be strictly greater + /// than the current major version held on-chain. The VM reads this information and can use it to + /// preserve backwards compatibility with previous major versions of the VM. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `major` | `u64` | The `major` version of the VM to be used from this transaction on. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + /// | `Errors::INVALID_ARGUMENT` | `DiemVersion::EINVALID_MAJOR_VERSION_NUMBER` | `major` is less-than or equal to the current major version stored on-chain. | + + public entry fun update_diem_version(account: signer, sliding_nonce: u64, major: u64) { + SlidingNonce::record_nonce_or_abort(&account, sliding_nonce); + DiemVersion::set(&account, major) + } + + /// # Summary + /// Updates the gas constants stored on chain and used by the VM for gas + /// metering. This transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Updates the on-chain config holding the `DiemVMConfig` and emits a + /// `DiemConfig::NewEpochEvent` to trigger a reconfiguration of the system. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `global_memory_per_byte_cost` | `u64` | The new cost to read global memory per-byte to be used for gas metering. | + /// | `global_memory_per_byte_write_cost` | `u64` | The new cost to write global memory per-byte to be used for gas metering. | + /// | `min_transaction_gas_units` | `u64` | The new flat minimum amount of gas required for any transaction. | + /// | `large_transaction_cutoff` | `u64` | The new size over which an additional charge will be assessed for each additional byte. | + /// | `intrinsic_gas_per_byte` | `u64` | The new number of units of gas that to be charged per-byte over the new `large_transaction_cutoff`. | + /// | `maximum_number_of_gas_units` | `u64` | The new maximum number of gas units that can be set in a transaction. | + /// | `min_price_per_gas_unit` | `u64` | The new minimum gas price that can be set for a transaction. | + /// | `max_price_per_gas_unit` | `u64` | The new maximum gas price that can be set for a transaction. | + /// | `max_transaction_size_in_bytes` | `u64` | The new maximum size of a transaction that can be processed. | + /// | `gas_unit_scaling_factor` | `u64` | The new scaling factor to use when scaling between external and internal gas units. | + /// | `default_account_size` | `u64` | The new default account size to use when assessing final costs for reads and writes to global storage. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_ARGUMENT` | `DiemVMConfig::EGAS_CONSTANT_INCONSISTENCY` | The provided gas constants are inconsistent. | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + public entry fun set_gas_constants( + dr_account: signer, + sliding_nonce: u64, + global_memory_per_byte_cost: u64, + global_memory_per_byte_write_cost: u64, + min_transaction_gas_units: u64, + large_transaction_cutoff: u64, + intrinsic_gas_per_byte: u64, + maximum_number_of_gas_units: u64, + min_price_per_gas_unit: u64, + max_price_per_gas_unit: u64, + max_transaction_size_in_bytes: u64, + gas_unit_scaling_factor: u64, + default_account_size: u64, + ) { + SlidingNonce::record_nonce_or_abort(&dr_account, sliding_nonce); + DiemVMConfig::set_gas_constants( + &dr_account, + global_memory_per_byte_cost, + global_memory_per_byte_write_cost, + min_transaction_gas_units, + large_transaction_cutoff, + intrinsic_gas_per_byte, + maximum_number_of_gas_units, + min_price_per_gas_unit, + max_price_per_gas_unit, + max_transaction_size_in_bytes, + gas_unit_scaling_factor, + default_account_size, + ) + } + + /// # Summary + /// Initializes the Diem consensus config that is stored on-chain. This + /// transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Initializes the `DiemConsensusConfig` on-chain config to empty and allows future updates from DiemRoot via + /// `update_diem_consensus_config`. This doesn't emit a `DiemConfig::NewEpochEvent`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + + public entry fun initialize_diem_consensus_config(account: signer, sliding_nonce: u64) { + SlidingNonce::record_nonce_or_abort(&account, sliding_nonce); + DiemConsensusConfig::initialize(&account); + } + + /// # Summary + /// Updates the Diem consensus config that is stored on-chain and is used by the Consensus. This + /// transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Updates the `DiemConsensusConfig` on-chain config and emits a `DiemConfig::NewEpochEvent` to trigger + /// a reconfiguration of the system. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `config` | `vector` | The serialized bytes of consensus config. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + + public entry fun update_diem_consensus_config(account: signer, sliding_nonce: u64, config: vector) { + SlidingNonce::record_nonce_or_abort(&account, sliding_nonce); + DiemConsensusConfig::set(&account, config) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/TransactionFee.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/TransactionFee.move new file mode 100644 index 000000000..9b6b94a5a --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/TransactionFee.move @@ -0,0 +1,175 @@ +/// Functions to initialize, accumulated, and burn transaction fees. +module DiemFramework::TransactionFee { + use DiemFramework::XUS::XUS; + use DiemFramework::XDX; + use DiemFramework::Diem::{Self, Diem, Preburn}; + use DiemFramework::Roles; + use DiemFramework::DiemTimestamp; + use std::errors; + use std::signer; + + /// The `TransactionFee` resource holds a preburn resource for each + /// fiat `CoinType` that can be collected as a transaction fee. + struct TransactionFee has key { + balance: Diem, + preburn: Preburn, + } + + /// A `TransactionFee` resource is not in the required state + const ETRANSACTION_FEE: u64 = 0; + + /// Called in genesis. Sets up the needed resources to collect transaction fees from the + /// `TransactionFee` resource with the TreasuryCompliance account. + public fun initialize( + tc_account: &signer, + ) { + DiemTimestamp::assert_genesis(); + Roles::assert_treasury_compliance(tc_account); + // accept fees in all the currencies + add_txn_fee_currency(tc_account); + } + spec initialize { + include DiemTimestamp::AbortsIfNotGenesis; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include AddTxnFeeCurrencyAbortsIf; + ensures is_initialized(); + ensures spec_transaction_fee().balance.value == 0; + } + spec schema AddTxnFeeCurrencyAbortsIf { + include Diem::AbortsIfNoCurrency; + aborts_if exists>(@TreasuryCompliance) + with errors::ALREADY_PUBLISHED; + } + + public fun is_coin_initialized(): bool { + exists>(@TreasuryCompliance) + } + + fun is_initialized(): bool { + is_coin_initialized() + } + + /// Sets up the needed transaction fee state for a given `CoinType` currency by + /// (1) configuring `tc_account` to accept `CoinType` + /// (2) publishing a wrapper of the `Preburn` resource under `tc_account` + public fun add_txn_fee_currency(tc_account: &signer) { + Roles::assert_treasury_compliance(tc_account); + Diem::assert_is_currency(); + assert!( + !is_coin_initialized(), + errors::already_published(ETRANSACTION_FEE) + ); + move_to( + tc_account, + TransactionFee { + balance: Diem::zero(), + preburn: Diem::create_preburn(tc_account) + } + ) + } + + /// Deposit `coin` into the transaction fees bucket + public fun pay_fee(coin: Diem) acquires TransactionFee { + DiemTimestamp::assert_operating(); + assert!(is_coin_initialized(), errors::not_published(ETRANSACTION_FEE)); + let fees = borrow_global_mut>(@TreasuryCompliance); + Diem::deposit(&mut fees.balance, coin) + } + + spec pay_fee { + include PayFeeAbortsIf; + include PayFeeEnsures; + } + spec schema PayFeeAbortsIf { + coin: Diem; + let fees = spec_transaction_fee().balance; + include DiemTimestamp::AbortsIfNotOperating; + aborts_if !is_coin_initialized() with errors::NOT_PUBLISHED; + include Diem::DepositAbortsIf{coin: fees, check: coin}; + } + spec schema PayFeeEnsures { + coin: Diem; + let fees = spec_transaction_fee().balance; + let post post_fees = spec_transaction_fee().balance; + ensures post_fees.value == fees.value + coin.value; + } + + /// Preburns the transaction fees collected in the `CoinType` currency. + /// If the `CoinType` is XDX, it unpacks the coin and preburns the + /// underlying fiat. + public fun burn_fees( + tc_account: &signer, + ) acquires TransactionFee { + DiemTimestamp::assert_operating(); + Roles::assert_treasury_compliance(tc_account); + assert!(is_coin_initialized(), errors::not_published(ETRANSACTION_FEE)); + if (XDX::is_xdx()) { + // TODO: Once the composition of XDX is determined fill this in to + // unpack and burn the backing coins of the XDX coin. + abort errors::invalid_state(ETRANSACTION_FEE) + } else { + // extract fees + let fees = borrow_global_mut>(@TreasuryCompliance); + let coin = Diem::withdraw_all(&mut fees.balance); + let burn_cap = Diem::remove_burn_capability(tc_account); + // burn + Diem::burn_now( + coin, + &mut fees.preburn, + @TreasuryCompliance, + &burn_cap + ); + Diem::publish_burn_capability(tc_account, burn_cap); + } + } + spec burn_fees { + pragma disable_invariants_in_body; + /// Must abort if the account does not have the TreasuryCompliance role [[H3]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + + include DiemTimestamp::AbortsIfNotOperating; + aborts_if !is_coin_initialized() with errors::NOT_PUBLISHED; + include if (XDX::spec_is_xdx()) BurnFeesXDX else BurnFeesNotXDX; + + /// The correct amount of fees is burnt and subtracted from market cap. + ensures Diem::spec_market_cap() + == old(Diem::spec_market_cap()) - old(spec_transaction_fee().balance.value); + /// All the fees is burnt so the balance becomes 0. + ensures spec_transaction_fee().balance.value == 0; + } + /// STUB: To be filled in at a later date once the makeup of the XDX has been determined. + /// + /// # Specification of the case where burn type is XDX. + spec schema BurnFeesXDX { + tc_account: signer; + aborts_if true with errors::INVALID_STATE; + } + /// # Specification of the case where burn type is not XDX. + spec schema BurnFeesNotXDX { + tc_account: signer; + /// Must abort if the account does not have BurnCapability [[H3]][PERMISSION]. + include Diem::AbortsIfNoBurnCapability{account: tc_account}; + + let fees = spec_transaction_fee(); + include Diem::BurnNowAbortsIf{coin: fees.balance, preburn: fees.preburn}; + + /// tc_account retrieves BurnCapability [[H3]][PERMISSION]. + /// BurnCapability is not transferrable [[J3]][PERMISSION]. + ensures exists>(signer::address_of(tc_account)); + } + + spec module {} // Switch documentation context to module level. + + /// # Initialization + + spec module { + /// If time has started ticking, then `TransactionFee` resources have been initialized. + invariant [suspendable] DiemTimestamp::is_operating() ==> is_initialized(); + } + + /// # Helper Function + + spec fun spec_transaction_fee(): TransactionFee { + borrow_global>(@TreasuryCompliance) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/TreasuryComplianceScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/TreasuryComplianceScripts.move new file mode 100644 index 000000000..ac7d02b76 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/TreasuryComplianceScripts.move @@ -0,0 +1,727 @@ +/// This module holds scripts relating to treasury and compliance-related +/// activities in the Diem Framework. +/// +/// Only accounts with a role of `Roles::TREASURY_COMPLIANCE` and +/// `Roles::DESIGNATED_DEALER` can (successfully) use the scripts in this +/// module. The exact role required for a transaction is determined on a +/// per-transaction basis. +module DiemFramework::TreasuryComplianceScripts { + use DiemFramework::DiemAccount; + use DiemFramework::Diem; + use DiemFramework::SlidingNonce; + use DiemFramework::TransactionFee; + use DiemFramework::AccountFreezing; + use DiemFramework::DualAttestation; + use DiemFramework::VASPDomain; + use std::fixed_point32; + + /// # Summary + /// Cancels and returns the coins held in the preburn area under + /// `preburn_address`, which are equal to the `amount` specified in the transaction. Finds the first preburn + /// resource with the matching amount and returns the funds to the `preburn_address`'s balance. + /// Can only be successfully sent by an account with Treasury Compliance role. + /// + /// # Technical Description + /// Cancels and returns all coins held in the `Diem::Preburn` resource under the `preburn_address` and + /// return the funds to the `preburn_address` account's `DiemAccount::Balance`. + /// The transaction must be sent by an `account` with a `Diem::BurnCapability` + /// resource published under it. The account at `preburn_address` must have a + /// `Diem::Preburn` resource published under it, and its value must be nonzero. The transaction removes + /// the entire balance held in the `Diem::Preburn` resource, and returns it back to the account's + /// `DiemAccount::Balance` under `preburn_address`. Due to this, the account at + /// `preburn_address` must already have a balance in the `Token` currency published + /// before this script is called otherwise the transaction will fail. + /// + /// # Events + /// The successful execution of this transaction will emit: + /// * A `Diem::CancelBurnEvent` on the event handle held in the `Diem::CurrencyInfo` + /// resource's `burn_events` published under `0xA550C18`. + /// * A `DiemAccount::ReceivedPaymentEvent` on the `preburn_address`'s + /// `DiemAccount::DiemAccount` `received_events` event handle with both the `payer` and `payee` + /// being `preburn_address`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Token` | Type | The Move type for the `Token` currenty that burning is being cancelled for. `Token` must be an already-registered currency on-chain. | + /// | `account` | `signer` | The signer of the sending account of this transaction, must have a burn capability for `Token` published under it. | + /// | `preburn_address` | `address` | The address where the coins to-be-burned are currently held. | + /// | `amount` | `u64` | The amount to be cancelled. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_CAPABILITY` | `Diem::EBURN_CAPABILITY` | The sending `account` does not have a `Diem::BurnCapability` published under it. | + /// | `Errors::INVALID_STATE` | `Diem::EPREBURN_NOT_FOUND` | The `Diem::PreburnQueue` resource under `preburn_address` does not contain a preburn request with a value matching `amount`. | + /// | `Errors::NOT_PUBLISHED` | `Diem::EPREBURN_QUEUE` | The account at `preburn_address` does not have a `Diem::PreburnQueue` resource published under it. | + /// | `Errors::NOT_PUBLISHED` | `Diem::ECURRENCY_INFO` | The specified `Token` is not a registered currency on-chain. | + /// | `Errors::INVALID_ARGUMENT` | `DiemAccount::EPAYEE_CANT_ACCEPT_CURRENCY_TYPE` | The account at `preburn_address` doesn't have a balance resource for `Token`. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EDEPOSIT_EXCEEDS_LIMITS` | The depositing of the funds held in the prebun area would exceed the `account`'s account limits. | + /// | `Errors::INVALID_STATE` | `DualAttestation::EPAYEE_COMPLIANCE_KEY_NOT_SET` | The `account` does not have a compliance key set on it but dual attestion checking was performed. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::burn_txn_fees` + /// * `TreasuryComplianceScripts::burn_with_amount` + /// * `TreasuryComplianceScripts::preburn` + + public entry fun cancel_burn_with_amount(account: signer, preburn_address: address, amount: u64) { + DiemAccount::cancel_burn(&account, preburn_address, amount) + } + + spec cancel_burn_with_amount { + use std::errors; + use DiemFramework::Diem; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include DiemAccount::CancelBurnAbortsIf; + include Diem::CancelBurnWithCapEnsures; + include DiemAccount::DepositEnsures{payee: preburn_address}; + + let total_preburn_value = global>( + @CurrencyInfo + ).preburn_value; + let post post_total_preburn_value = global>( + @CurrencyInfo + ).preburn_value; + + let balance_at_addr = DiemAccount::balance(preburn_address); + let post post_balance_at_addr = DiemAccount::balance(preburn_address); + + /// The total value of preburn for `Token` should decrease by the preburned amount. + ensures post_total_preburn_value == total_preburn_value - amount; + + /// The balance of `Token` at `preburn_address` should increase by the preburned amount. + ensures post_balance_at_addr == balance_at_addr + amount; + + include Diem::CancelBurnWithCapEmits; + include DiemAccount::DepositEmits{ + payer: preburn_address, + payee: preburn_address, + amount: amount, + metadata: x"" + }; + + aborts_with [check] + errors::REQUIRES_CAPABILITY, + errors::NOT_PUBLISHED, + errors::INVALID_ARGUMENT, + errors::LIMIT_EXCEEDED, + errors::INVALID_STATE; + + /// **Access Control:** + /// Only the account with the burn capability can cancel burning [[H3]][PERMISSION]. + include Diem::AbortsIfNoBurnCapability{account: account}; + } + + /// # Summary + /// Burns the coins held in a preburn resource in the preburn queue at the + /// specified preburn address, which are equal to the `amount` specified in the + /// transaction. Finds the first relevant outstanding preburn request with + /// matching amount and removes the contained coins from the system. The sending + /// account must be the Treasury Compliance account. + /// The account that holds the preburn queue resource will normally be a Designated + /// Dealer, but there are no enforced requirements that it be one. + /// + /// # Technical Description + /// This transaction permanently destroys all the coins of `Token` type + /// stored in the `Diem::Preburn` resource published under the + /// `preburn_address` account address. + /// + /// This transaction will only succeed if the sending `account` has a + /// `Diem::BurnCapability`, and a `Diem::Preburn` resource + /// exists under `preburn_address`, with a non-zero `to_burn` field. After the successful execution + /// of this transaction the `total_value` field in the + /// `Diem::CurrencyInfo` resource published under `0xA550C18` will be + /// decremented by the value of the `to_burn` field of the preburn resource + /// under `preburn_address` immediately before this transaction, and the + /// `to_burn` field of the preburn resource will have a zero value. + /// + /// # Events + /// The successful execution of this transaction will emit a `Diem::BurnEvent` on the event handle + /// held in the `Diem::CurrencyInfo` resource's `burn_events` published under + /// `0xA550C18`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Token` | Type | The Move type for the `Token` currency being burned. `Token` must be an already-registered currency on-chain. | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction, must have a burn capability for `Token` published under it. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `preburn_address` | `address` | The address where the coins to-be-burned are currently held. | + /// | `amount` | `u64` | The amount to be burned. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_CAPABILITY` | `Diem::EBURN_CAPABILITY` | The sending `account` does not have a `Diem::BurnCapability` published under it. | + /// | `Errors::INVALID_STATE` | `Diem::EPREBURN_NOT_FOUND` | The `Diem::PreburnQueue` resource under `preburn_address` does not contain a preburn request with a value matching `amount`. | + /// | `Errors::NOT_PUBLISHED` | `Diem::EPREBURN_QUEUE` | The account at `preburn_address` does not have a `Diem::PreburnQueue` resource published under it. | + /// | `Errors::NOT_PUBLISHED` | `Diem::ECURRENCY_INFO` | The specified `Token` is not a registered currency on-chain. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::burn_txn_fees` + /// * `TreasuryComplianceScripts::cancel_burn_with_amount` + /// * `TreasuryComplianceScripts::preburn` + + public entry fun burn_with_amount(account: signer, sliding_nonce: u64, preburn_address: address, amount: u64) { + SlidingNonce::record_nonce_or_abort(&account, sliding_nonce); + Diem::burn(&account, preburn_address, amount) + } + spec burn_with_amount { + use std::errors; + use DiemFramework::DiemAccount; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{ seq_nonce: sliding_nonce }; + include Diem::BurnAbortsIf; + include Diem::BurnEnsures; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::REQUIRES_CAPABILITY, + errors::NOT_PUBLISHED, + errors::INVALID_STATE, + errors::LIMIT_EXCEEDED; + + include Diem::BurnWithResourceCapEmits{preburn: Diem::spec_make_preburn(amount)}; + + /// **Access Control:** + /// Only the account with the burn capability can burn coins [[H3]][PERMISSION]. + include Diem::AbortsIfNoBurnCapability{account: account}; + } + + /// # Summary + /// Moves a specified number of coins in a given currency from the account's + /// balance to its preburn area after which the coins may be burned. This + /// transaction may be sent by any account that holds a balance and preburn area + /// in the specified currency. + /// + /// # Technical Description + /// Moves the specified `amount` of coins in `Token` currency from the sending `account`'s + /// `DiemAccount::Balance` to the `Diem::Preburn` published under the same + /// `account`. `account` must have both of these resources published under it at the start of this + /// transaction in order for it to execute successfully. + /// + /// # Events + /// Successful execution of this script emits two events: + /// * `DiemAccount::SentPaymentEvent ` on `account`'s `DiemAccount::DiemAccount` `sent_events` + /// handle with the `payee` and `payer` fields being `account`'s address; and + /// * A `Diem::PreburnEvent` with `Token`'s currency code on the + /// `Diem::CurrencyInfo` resource published under it. | + /// | `Errors::INVALID_STATE` | `Diem::EPREBURN_OCCUPIED` | The `value` field in the `Diem::Preburn` resource under the sender is non-zero. | + /// | `Errors::NOT_PUBLISHED` | `Roles::EROLE_ID` | The `account` did not have a role assigned to it. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EDESIGNATED_DEALER` | The `account` did not have the role of DesignatedDealer. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::cancel_burn_with_amount` + /// * `TreasuryComplianceScripts::burn_with_amount` + /// * `TreasuryComplianceScripts::burn_txn_fees` + + public entry fun preburn(account: signer, amount: u64) { + let withdraw_cap = DiemAccount::extract_withdraw_capability(&account); + DiemAccount::preburn(&account, &withdraw_cap, amount); + DiemAccount::restore_withdraw_capability(withdraw_cap); + } + + spec preburn { + use std::errors; + use std::signer; + use DiemFramework::Diem; + + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + let account_addr = signer::address_of(account); + let cap = DiemAccount::spec_get_withdraw_cap(account_addr); + include DiemAccount::ExtractWithdrawCapAbortsIf{sender_addr: account_addr}; + include DiemAccount::PreburnAbortsIf{dd: account, cap: cap}; + include DiemAccount::PreburnEnsures{dd: account, payer: account_addr}; + + include DiemAccount::PreburnEmits{dd: account, cap: cap}; + + aborts_with [check] + errors::NOT_PUBLISHED, + errors::INVALID_STATE, + errors::REQUIRES_ROLE, + errors::LIMIT_EXCEEDED; + + /// **Access Control:** + /// Only the account with a Preburn resource or PreburnQueue resource can preburn [[H4]][PERMISSION]. + aborts_if !(exists>(account_addr) || exists>(account_addr)); + } + + /// # Summary + /// Burns the transaction fees collected in the `CoinType` currency so that the + /// Diem association may reclaim the backing coins off-chain. May only be sent + /// by the Treasury Compliance account. + /// + /// # Technical Description + /// Burns the transaction fees collected in `CoinType` so that the + /// association may reclaim the backing coins. Once this transaction has executed + /// successfully all transaction fees that will have been collected in + /// `CoinType` since the last time this script was called with that specific + /// currency. Both `balance` and `preburn` fields in the + /// `TransactionFee::TransactionFee` resource published under the `0xB1E55ED` + /// account address will have a value of 0 after the successful execution of this script. + /// + /// # Events + /// The successful execution of this transaction will emit a `Diem::BurnEvent` on the event handle + /// held in the `Diem::CurrencyInfo` resource's `burn_events` published under + /// `0xA550C18`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `CoinType` | Type | The Move type for the `CoinType` being added to the sending account of the transaction. `CoinType` must be an already-registered currency on-chain. | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `TransactionFee::ETRANSACTION_FEE` | `CoinType` is not an accepted transaction fee currency. | + /// | `Errors::INVALID_ARGUMENT` | `Diem::ECOIN` | The collected fees in `CoinType` are zero. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::burn_with_amount` + /// * `TreasuryComplianceScripts::cancel_burn_with_amount` + + public entry fun burn_txn_fees(tc_account: signer) { + TransactionFee::burn_fees(&tc_account); + } + + /// # Summary + /// Mints a specified number of coins in a currency to a Designated Dealer. The sending account + /// must be the Treasury Compliance account, and coins can only be minted to a Designated Dealer + /// account. + /// + /// # Technical Description + /// Mints `mint_amount` of coins in the `CoinType` currency to Designated Dealer account at + /// `designated_dealer_address`. The `tier_index` parameter specifies which tier should be used to + /// check verify the off-chain approval policy, and is based in part on the on-chain tier values + /// for the specific Designated Dealer, and the number of `CoinType` coins that have been minted to + /// the dealer over the past 24 hours. Every Designated Dealer has 4 tiers for each currency that + /// they support. The sending `tc_account` must be the Treasury Compliance account, and the + /// receiver an authorized Designated Dealer account. + /// + /// # Events + /// Successful execution of the transaction will emit two events: + /// * A `Diem::MintEvent` with the amount and currency code minted is emitted on the + /// `mint_event_handle` in the stored `Diem::CurrencyInfo` resource stored under + /// `0xA550C18`; and + /// * A `DesignatedDealer::ReceivedMintEvent` with the amount, currency code, and Designated + /// Dealer's address is emitted on the `mint_event_handle` in the stored `DesignatedDealer::Dealer` + /// resource published under the `designated_dealer_address`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `CoinType` | Type | The Move type for the `CoinType` being minted. `CoinType` must be an already-registered currency on-chain. | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `designated_dealer_address` | `address` | The address of the Designated Dealer account being minted to. | + /// | `mint_amount` | `u64` | The number of coins to be minted. | + /// | `tier_index` | `u64` | [Deprecated] The mint tier index to use for the Designated Dealer account. Will be ignored | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `tc_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// | `Errors::INVALID_ARGUMENT` | `DesignatedDealer::EINVALID_MINT_AMOUNT` | `mint_amount` is zero. | + /// | `Errors::NOT_PUBLISHED` | `DesignatedDealer::EDEALER` | `DesignatedDealer::Dealer` or `DesignatedDealer::TierInfo` resource does not exist at `designated_dealer_address`. | + /// | `Errors::REQUIRES_CAPABILITY` | `Diem::EMINT_CAPABILITY` | `tc_account` does not have a `Diem::MintCapability` resource published under it. | + /// | `Errors::INVALID_STATE` | `Diem::EMINTING_NOT_ALLOWED` | Minting is not currently allowed for `CoinType` coins. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemAccount::EDEPOSIT_EXCEEDS_LIMITS` | The depositing of the funds would exceed the `account`'s account limits. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_designated_dealer` + /// * `PaymentScripts::peer_to_peer_with_metadata` + /// * `AccountAdministrationScripts::rotate_dual_attestation_info` + + public entry fun tiered_mint( + tc_account: signer, + sliding_nonce: u64, + designated_dealer_address: address, + mint_amount: u64, + tier_index: u64 + ) { + SlidingNonce::record_nonce_or_abort(&tc_account, sliding_nonce); + DiemAccount::tiered_mint( + &tc_account, designated_dealer_address, mint_amount, tier_index + ); + } + + spec tiered_mint { + use std::errors; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: tc_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{account: tc_account, seq_nonce: sliding_nonce}; + include DiemAccount::TieredMintAbortsIf; + include DiemAccount::TieredMintEnsures; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::REQUIRES_ADDRESS, + errors::NOT_PUBLISHED, + errors::REQUIRES_CAPABILITY, + errors::INVALID_STATE, + errors::LIMIT_EXCEEDED, + errors::REQUIRES_ROLE; + + include DiemAccount::TieredMintEmits; + + /// **Access Control:** + /// Only the Treasury Compliance account can mint [[H1]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + } + + /// # Summary + /// Freezes the account at `address`. The sending account of this transaction + /// must be the Treasury Compliance account. The account being frozen cannot be + /// the Diem Root or Treasury Compliance account. After the successful + /// execution of this transaction no transactions may be sent from the frozen + /// account, and the frozen account may not send or receive coins. + /// + /// # Technical Description + /// Sets the `AccountFreezing::FreezingBit` to `true` and emits a + /// `AccountFreezing::FreezeAccountEvent`. The transaction sender must be the + /// Treasury Compliance account, but the account at `to_freeze_account` must + /// not be either `0xA550C18` (the Diem Root address), or `0xB1E55ED` (the + /// Treasury Compliance address). Note that this is a per-account property + /// e.g., freezing a Parent VASP will not effect the status any of its child + /// accounts and vice versa. + /// + /// + /// # Events + /// Successful execution of this transaction will emit a `AccountFreezing::FreezeAccountEvent` on + /// the `freeze_event_handle` held in the `AccountFreezing::FreezeEventsHolder` resource published + /// under `0xA550C18` with the `frozen_address` being the `to_freeze_account`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `to_freeze_account` | `address` | The account address to be frozen. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `tc_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::INVALID_ARGUMENT` | `AccountFreezing::ECANNOT_FREEZE_TC` | `to_freeze_account` was the Treasury Compliance account (`0xB1E55ED`). | + /// | `Errors::INVALID_ARGUMENT` | `AccountFreezing::ECANNOT_FREEZE_DIEM_ROOT` | `to_freeze_account` was the Diem Root account (`0xA550C18`). | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::unfreeze_account` + + public entry fun freeze_account(tc_account: signer, sliding_nonce: u64, to_freeze_account: address) { + SlidingNonce::record_nonce_or_abort(&tc_account, sliding_nonce); + AccountFreezing::freeze_account(&tc_account, to_freeze_account); + } + + /// # Summary + /// Unfreezes the account at `address`. The sending account of this transaction must be the + /// Treasury Compliance account. After the successful execution of this transaction transactions + /// may be sent from the previously frozen account, and coins may be sent and received. + /// + /// # Technical Description + /// Sets the `AccountFreezing::FreezingBit` to `false` and emits a + /// `AccountFreezing::UnFreezeAccountEvent`. The transaction sender must be the Treasury Compliance + /// account. Note that this is a per-account property so unfreezing a Parent VASP will not effect + /// the status any of its child accounts and vice versa. + /// + /// # Events + /// Successful execution of this script will emit a `AccountFreezing::UnFreezeAccountEvent` with + /// the `unfrozen_address` set the `to_unfreeze_account`'s address. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `to_unfreeze_account` | `address` | The account address to be frozen. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::freeze_account` + + public entry fun unfreeze_account(account: signer, sliding_nonce: u64, to_unfreeze_account: address) { + SlidingNonce::record_nonce_or_abort(&account, sliding_nonce); + AccountFreezing::unfreeze_account(&account, to_unfreeze_account); + } + + /// # Summary + /// Update the dual attestation limit on-chain. Defined in terms of micro-XDX. The transaction can + /// only be sent by the Treasury Compliance account. After this transaction all inter-VASP + /// payments over this limit must be checked for dual attestation. + /// + /// # Technical Description + /// Updates the `micro_xdx_limit` field of the `DualAttestation::Limit` resource published under + /// `0xA550C18`. The amount is set in micro-XDX. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `new_micro_xdx_limit` | `u64` | The new dual attestation limit to be used on-chain. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `tc_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::update_exchange_rate` + /// * `TreasuryComplianceScripts::update_minting_ability` + + public entry fun update_dual_attestation_limit( + tc_account: signer, + sliding_nonce: u64, + new_micro_xdx_limit: u64 + ) { + SlidingNonce::record_nonce_or_abort(&tc_account, sliding_nonce); + DualAttestation::set_microdiem_limit(&tc_account, new_micro_xdx_limit); + } + + /// # Summary + /// Update the rough on-chain exchange rate between a specified currency and XDX (as a conversion + /// to micro-XDX). The transaction can only be sent by the Treasury Compliance account. After this + /// transaction the updated exchange rate will be used for normalization of gas prices, and for + /// dual attestation checking. + /// + /// # Technical Description + /// Updates the on-chain exchange rate from the given `Currency` to micro-XDX. The exchange rate + /// is given by `new_exchange_rate_numerator/new_exchange_rate_denominator`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Currency` | Type | The Move type for the `Currency` whose exchange rate is being updated. `Currency` must be an already-registered currency on-chain. | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for the transaction. | + /// | `new_exchange_rate_numerator` | `u64` | The numerator for the new to micro-XDX exchange rate for `Currency`. | + /// | `new_exchange_rate_denominator` | `u64` | The denominator for the new to micro-XDX exchange rate for `Currency`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `tc_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// | `Errors::INVALID_ARGUMENT` | `FixedPoint32::EDENOMINATOR` | `new_exchange_rate_denominator` is zero. | + /// | `Errors::INVALID_ARGUMENT` | `FixedPoint32::ERATIO_OUT_OF_RANGE` | The quotient is unrepresentable as a `FixedPoint32`. | + /// | `Errors::LIMIT_EXCEEDED` | `FixedPoint32::ERATIO_OUT_OF_RANGE` | The quotient is unrepresentable as a `FixedPoint32`. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::update_dual_attestation_limit` + /// * `TreasuryComplianceScripts::update_minting_ability` + + public entry fun update_exchange_rate( + tc_account: signer, + sliding_nonce: u64, + new_exchange_rate_numerator: u64, + new_exchange_rate_denominator: u64, + ) { + SlidingNonce::record_nonce_or_abort(&tc_account, sliding_nonce); + let rate = fixed_point32::create_from_rational( + new_exchange_rate_numerator, + new_exchange_rate_denominator, + ); + Diem::update_xdx_exchange_rate(&tc_account, rate); + } + spec update_exchange_rate { + use std::errors; + use DiemFramework::DiemAccount; + use DiemFramework::Roles; + + include DiemAccount::TransactionChecks{sender: tc_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{ account: tc_account, seq_nonce: sliding_nonce }; + include fixed_point32::CreateFromRationalAbortsIf{ + numerator: new_exchange_rate_numerator, + denominator: new_exchange_rate_denominator + }; + let rate = fixed_point32::spec_create_from_rational( + new_exchange_rate_numerator, + new_exchange_rate_denominator + ); + include Diem::UpdateXDXExchangeRateAbortsIf; + include Diem::UpdateXDXExchangeRateEnsures{xdx_exchange_rate: rate}; + include Diem::UpdateXDXExchangeRateEmits{xdx_exchange_rate: rate}; + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::REQUIRES_ADDRESS, + errors::LIMIT_EXCEEDED, + errors::REQUIRES_ROLE, + errors::NOT_PUBLISHED; + + /// **Access Control:** + /// Only the Treasury Compliance account can update the exchange rate [[H5]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + } + + /// # Summary + /// Script to allow or disallow minting of new coins in a specified currency. This transaction can + /// only be sent by the Treasury Compliance account. Turning minting off for a currency will have + /// no effect on coins already in circulation, and coins may still be removed from the system. + /// + /// # Technical Description + /// This transaction sets the `can_mint` field of the `Diem::CurrencyInfo` resource + /// published under `0xA550C18` to the value of `allow_minting`. Minting of coins if allowed if + /// this field is set to `true` and minting of new coins in `Currency` is disallowed otherwise. + /// This transaction needs to be sent by the Treasury Compliance account. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `Currency` | Type | The Move type for the `Currency` whose minting ability is being updated. `Currency` must be an already-registered currency on-chain. | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `allow_minting` | `bool` | Whether to allow minting of new coins in `Currency`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `Diem::ECURRENCY_INFO` | `Currency` is not a registered currency on-chain. | + /// + /// # Related Scripts + /// * `TreasuryComplianceScripts::update_dual_attestation_limit` + /// * `TreasuryComplianceScripts::update_exchange_rate` + + public entry fun update_minting_ability( + tc_account: signer, + allow_minting: bool + ) { + Diem::update_minting_ability(&tc_account, allow_minting); + } + + /// # Summary + /// Add a VASP domain to parent VASP account. The transaction can only be sent by + /// the Treasury Compliance account. + /// + /// # Technical Description + /// Adds a `VASPDomain::VASPDomain` to the `domains` field of the `VASPDomain::VASPDomains` resource published under + /// the account at `address`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `address` | `address` | The `address` of the parent VASP account that will have have `domain` added to its domains. | + /// | `domain` | `vector` | The domain to be added. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_ROLE` | `Roles::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `VASPDomain::EVASP_DOMAIN_MANAGER` | The `VASPDomain::VASPDomainManager` resource is not yet published under the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `VASPDomain::EVASP_DOMAINS_NOT_PUBLISHED` | `address` does not have a `VASPDomain::VASPDomains` resource published under it. | + /// | `Errors::INVALID_ARGUMENT` | `VASPDomain::EDOMAIN_ALREADY_EXISTS` | The `domain` already exists in the list of `VASPDomain::VASPDomain`s in the `VASPDomain::VASPDomains` resource published under `address`. | + /// | `Errors::INVALID_ARGUMENT` | `VASPDomain::EINVALID_VASP_DOMAIN` | The `domain` is greater in length than `VASPDomain::DOMAIN_LENGTH`. | + public entry fun add_vasp_domain ( + tc_account: signer, + address: address, + domain: vector, + ) { + VASPDomain::add_vasp_domain(&tc_account, address, domain); + } + spec add_vasp_domain { + use std::errors; + include DiemAccount::TransactionChecks{sender: tc_account}; // properties checked by the prologue. + include VASPDomain::AddVASPDomainAbortsIf; + include VASPDomain::AddVASPDomainEnsures; + include VASPDomain::AddVASPDomainEmits; + aborts_with [check] + errors::REQUIRES_ROLE, + errors::REQUIRES_ADDRESS, + errors::NOT_PUBLISHED, + errors::INVALID_ARGUMENT; + } + + /// # Summary + /// Remove a VASP domain from parent VASP account. The transaction can only be sent by + /// the Treasury Compliance account. + /// + /// # Technical Description + /// Removes a `VASPDomain::VASPDomain` from the `domains` field of the `VASPDomain::VASPDomains` resource published under + /// account with `address`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `tc_account` | `signer` | The signer of the sending account of this transaction. Must be the Treasury Compliance account. | + /// | `address` | `address` | The `address` of parent VASP account that will update its domains. | + /// | `domain` | `vector` | The domain name. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_ROLE` | `Roles::ETREASURY_COMPLIANCE` | The sending account is not the Treasury Compliance account. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::ETREASURY_COMPLIANCE` | `tc_account` is not the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `VASPDomain::EVASP_DOMAIN_MANAGER` | The `VASPDomain::VASPDomainManager` resource is not yet published under the Treasury Compliance account. | + /// | `Errors::NOT_PUBLISHED` | `VASPDomain::EVASP_DOMAINS_NOT_PUBLISHED` | `address` does not have a `VASPDomain::VASPDomains` resource published under it. | + /// | `Errors::INVALID_ARGUMENT` | `VASPDomain::EINVALID_VASP_DOMAIN` | The `domain` is greater in length than `VASPDomain::DOMAIN_LENGTH`. | + /// | `Errors::INVALID_ARGUMENT` | `VASPDomain::EVASP_DOMAIN_NOT_FOUND` | The `domain` does not exist in the list of `VASPDomain::VASPDomain`s in the `VASPDomain::VASPDomains` resource published under `address`. | + public entry fun remove_vasp_domain ( + tc_account: signer, + address: address, + domain: vector, + ) { + VASPDomain::remove_vasp_domain(&tc_account, address, domain); + } + spec remove_vasp_domain { + use std::errors; + aborts_with [check] + errors::REQUIRES_ROLE, + errors::REQUIRES_ADDRESS, + errors::NOT_PUBLISHED, + errors::INVALID_ARGUMENT; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/VASP.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/VASP.move new file mode 100644 index 000000000..4972ca627 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/VASP.move @@ -0,0 +1,269 @@ +/// A VASP is one type of balance-holding account on the blockchain. VASPs from a two-layer +/// hierarchy. The main account, called a "parent VASP" and a collection of "child VASP"s. +/// This module provides functions to manage VASP accounts. +module DiemFramework::VASP { + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use DiemFramework::AccountLimits; + use std::errors; + use std::signer; + friend DiemFramework::DiemAccount; + + /// Each VASP has a unique root account that holds a `ParentVASP` resource. This resource holds + /// the VASP's globally unique name and all of the metadata that other VASPs need to perform + /// off-chain protocols with this one. + struct ParentVASP has key { + /// Number of child accounts this parent has created. + num_children: u64 + } + + /// A resource that represents a child account of the parent VASP account at `parent_vasp_addr` + struct ChildVASP has key { parent_vasp_addr: address } + + /// The `ParentVASP` or `ChildVASP` resources are not in the required state + const EPARENT_OR_CHILD_VASP: u64 = 0; + /// The creation of a new Child VASP account would exceed the number of children permitted for a VASP + const ETOO_MANY_CHILDREN: u64 = 1; + /// The account must be a Parent or Child VASP account + const ENOT_A_VASP: u64 = 2; + /// The creating account must be a Parent VASP account + const ENOT_A_PARENT_VASP: u64 = 3; + + + /// Maximum number of child accounts that can be created by a single ParentVASP + const MAX_CHILD_ACCOUNTS: u64 = 65536; // 2^16 + + /////////////////////////////////////////////////////////////////////////// + // To-be parent-vasp called functions + /////////////////////////////////////////////////////////////////////////// + + /// Create a new `ParentVASP` resource under `vasp` + /// Aborts if `dr_account` is not the diem root account, + /// or if there is already a VASP (child or parent) at this account. + public(friend) fun publish_parent_vasp_credential(vasp: &signer, tc_account: &signer) { + DiemTimestamp::assert_operating(); + Roles::assert_treasury_compliance(tc_account); + Roles::assert_parent_vasp_role(vasp); + let vasp_addr = signer::address_of(vasp); + assert!(!is_vasp(vasp_addr), errors::already_published(EPARENT_OR_CHILD_VASP)); + move_to(vasp, ParentVASP { num_children: 0 }); + } + + spec publish_parent_vasp_credential { + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include Roles::AbortsIfNotParentVasp{account: vasp}; + let vasp_addr = signer::address_of(vasp); + aborts_if is_vasp(vasp_addr) with errors::ALREADY_PUBLISHED; + include PublishParentVASPEnsures{vasp_addr: vasp_addr}; + } + + spec schema PublishParentVASPEnsures { + vasp_addr: address; + ensures is_parent(vasp_addr); + ensures spec_num_children(vasp_addr) == 0; + } + + /// Create a child VASP resource for the `parent` + /// Aborts if `parent` is not a ParentVASP + public(friend) fun publish_child_vasp_credential( + parent: &signer, + child: &signer, + ) acquires ParentVASP { + Roles::assert_parent_vasp_role(parent); + Roles::assert_child_vasp_role(child); + let child_vasp_addr = signer::address_of(child); + assert!(!is_vasp(child_vasp_addr), errors::already_published(EPARENT_OR_CHILD_VASP)); + let parent_vasp_addr = signer::address_of(parent); + assert!(is_parent(parent_vasp_addr), errors::invalid_argument(ENOT_A_PARENT_VASP)); + let num_children = &mut borrow_global_mut(parent_vasp_addr).num_children; + // Abort if creating this child account would put the parent VASP over the limit + assert!(*num_children < MAX_CHILD_ACCOUNTS, errors::limit_exceeded(ETOO_MANY_CHILDREN)); + *num_children = *num_children + 1; + move_to(child, ChildVASP { parent_vasp_addr }); + } + spec publish_child_vasp_credential { + let child_addr = signer::address_of(child); + include PublishChildVASPAbortsIf{child_addr}; + // NB: This aborts condition is separated out so that `PublishChildVASPAbortsIf` can be used in + // `DiemAccount::create_child_vasp_account` since this doesn't hold of the new account in the pre-state. + include Roles::AbortsIfNotChildVasp{account: child_addr}; + include PublishChildVASPEnsures{parent_addr: signer::address_of(parent), child_addr: child_addr}; + } + + spec schema PublishChildVASPAbortsIf { + parent: signer; + child_addr: address; + let parent_addr = signer::address_of(parent); + include Roles::AbortsIfNotParentVasp{account: parent}; + aborts_if is_vasp(child_addr) with errors::ALREADY_PUBLISHED; + aborts_if !is_parent(parent_addr) with errors::INVALID_ARGUMENT; + aborts_if spec_num_children(parent_addr) + 1 > MAX_CHILD_ACCOUNTS with errors::LIMIT_EXCEEDED; + } + + spec schema PublishChildVASPEnsures { + parent_addr: address; + child_addr: address; + ensures spec_num_children(parent_addr) == old(spec_num_children(parent_addr)) + 1; + ensures is_child(child_addr); + ensures spec_parent_address(child_addr) == parent_addr; + } + + /// Return `true` if `addr` is a parent or child VASP whose parent VASP account contains an + /// `AccountLimits` resource. + /// Aborts if `addr` is not a VASP + public fun has_account_limits(addr: address): bool acquires ChildVASP { + AccountLimits::has_window_published(parent_address(addr)) + } + + /////////////////////////////////////////////////////////////////////////// + // Publicly callable APIs + /////////////////////////////////////////////////////////////////////////// + + /// Return `addr` if `addr` is a `ParentVASP` or its parent's address if it is a `ChildVASP` + /// Aborts otherwise + public fun parent_address(addr: address): address acquires ChildVASP { + if (is_parent(addr)) { + addr + } else if (is_child(addr)) { + borrow_global(addr).parent_vasp_addr + } else { // wrong account type, abort + abort(errors::invalid_argument(ENOT_A_VASP)) + } + } + spec parent_address { + pragma opaque; + aborts_if !is_parent(addr) && !is_child(addr) with errors::INVALID_ARGUMENT; + ensures result == spec_parent_address(addr); + } + spec module { + /// Spec version of `Self::parent_address`. + fun spec_parent_address(addr: address): address { + if (is_parent(addr)) { + addr + } else { + global(addr).parent_vasp_addr + } + } + fun spec_has_account_limits(addr: address): bool { + AccountLimits::has_window_published(spec_parent_address(addr)) + } + } + + /// Returns true if `addr` is a parent VASP. + public fun is_parent(addr: address): bool { + exists(addr) + } + spec is_parent { + pragma opaque = true; + aborts_if false; + ensures result == is_parent(addr); + } + + /// Returns true if `addr` is a child VASP. + public fun is_child(addr: address): bool { + exists(addr) + } + spec is_child { + pragma opaque = true; + aborts_if false; + ensures result == is_child(addr); + } + + /// Returns true if `addr` is a VASP. + public fun is_vasp(addr: address): bool { + is_parent(addr) || is_child(addr) + } + spec is_vasp { + pragma opaque = true; + aborts_if false; + ensures result == is_vasp(addr); + } + spec schema AbortsIfNotVASP { + addr: address; + aborts_if !is_vasp(addr); + } + + /// Returns true if both addresses are VASPs and they have the same parent address. + public fun is_same_vasp(addr1: address, addr2: address): bool acquires ChildVASP { + is_vasp(addr1) && is_vasp(addr2) && parent_address(addr1) == parent_address(addr2) + } + spec is_same_vasp { + pragma opaque = true; + aborts_if false; + ensures result == spec_is_same_vasp(addr1, addr2); + } + /// Spec version of `Self::is_same_vasp`. + spec fun spec_is_same_vasp(addr1: address, addr2: address): bool { + is_vasp(addr1) && is_vasp(addr2) && spec_parent_address(addr1) == spec_parent_address(addr2) + } + + + /// If `addr` is the address of a `ParentVASP`, return the number of children. + /// If it is the address of a ChildVASP, return the number of children of the parent. + /// The total number of accounts for this VASP is num_children() + 1 + /// Aborts if `addr` is not a ParentVASP or ChildVASP account + public fun num_children(addr: address): u64 acquires ChildVASP, ParentVASP { + // If parent VASP succeeds, the parent is guaranteed to exist. + *&borrow_global(parent_address(addr)).num_children + } + spec num_children { + aborts_if !is_vasp(addr) with errors::INVALID_ARGUMENT; + } + /// Spec version of `Self::num_children`. + spec fun spec_num_children(parent: address): u64 { + global(parent).num_children + } + + // **************** SPECIFICATIONS **************** + spec module {} // switch documentation context back to module level + + /// # Persistence of parent and child VASPs + spec module { + invariant update forall addr: address where old(is_parent(addr)): + is_parent(addr); + + invariant update forall addr: address where old(is_child(addr)): + is_child(addr); + } + + /// # Existence of Parents + spec module { + invariant + forall child_addr: address where is_child(child_addr): + is_parent(global(child_addr).parent_vasp_addr); + } + + /// # Creation of Child VASPs + + spec module { + /// Only a parent VASP calling `Self::publish_child_vasp_credential` can create + /// child VASPs. + apply ChildVASPsDontChange to *, * except publish_child_vasp_credential; + + /// The number of children of a parent VASP can only changed by adding + /// a child through `Self::publish_child_vast_credential`. + apply NumChildrenRemainsSame to * except publish_child_vasp_credential; + } + + spec schema ChildVASPsDontChange { + /// A ChildVASP resource is at an address if and only if it was there in the + /// previous state. + ensures forall a: address : exists(a) == old(exists(a)); + } + + spec schema NumChildrenRemainsSame { + ensures forall parent: address + where old(is_parent(parent)): + spec_num_children(parent) == old(spec_num_children(parent)); + } + + /// # Immutability of Parent Address + + spec module { + /// The parent address stored at ChildVASP resource never changes. + invariant update + forall a: address where old(is_child(a)): spec_parent_address(a) == old(spec_parent_address(a)); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/VASPDomain.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/VASPDomain.move new file mode 100644 index 000000000..57d4218aa --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/VASPDomain.move @@ -0,0 +1,305 @@ +/// Module managing VASP domains. +module DiemFramework::VASPDomain { + use DiemFramework::Roles; + use std::errors; + use std::event::{Self, EventHandle}; + use std::signer; + use std::vector; + friend DiemFramework::DiemAccount; + friend DiemFramework::AccountAdministrationScripts; + + /// This resource holds an entity's domain names. + struct VASPDomains has key { + /// The list of domain names owned by this parent vasp account + domains: vector, + } + spec VASPDomains { + /// All `VASPDomain`s stored in the `VASPDomains` resource are no more than 63 characters long. + invariant forall i in 0..len(domains): len(domains[i].domain) <= DOMAIN_LENGTH; + /// The list of `VASPDomain`s are a set + invariant forall i in 0..len(domains): + forall j in i + 1..len(domains): domains[i] != domains[j]; + } + + /// Struct to store the limit on-chain + struct VASPDomain has drop, store, copy { + domain: vector, // UTF-8 encoded and 63 characters + } + spec VASPDomain { + /// All `VASPDomain`s must be no more than 63 characters long. + invariant len(domain) <= DOMAIN_LENGTH; + } + + struct VASPDomainManager has key { + /// Event handle for `domains` added or removed events. Emitted every time a domain is added + /// or removed to `domains` + vasp_domain_events: EventHandle, + } + + struct VASPDomainEvent has drop, store { + /// Whether a domain was added or removed + removed: bool, + /// VASP Domain string of the account + domain: VASPDomain, + /// On-chain account address + address: address, + } + + const DOMAIN_LENGTH: u64 = 63; + + // Error codes + /// VASPDomains resource is not or already published. + const EVASP_DOMAINS: u64 = 0; + /// VASPDomainManager resource is not or already published. + const EVASP_DOMAIN_MANAGER: u64 = 1; + /// VASP domain was not found + const EVASP_DOMAIN_NOT_FOUND: u64 = 2; + /// VASP domain already exists + const EVASP_DOMAIN_ALREADY_EXISTS: u64 = 3; + /// VASPDomains resource was not published for a VASP account + const EVASP_DOMAINS_NOT_PUBLISHED: u64 = 4; + /// Invalid domain for VASPDomain + const EINVALID_VASP_DOMAIN: u64 = 5; + + fun create_vasp_domain(domain: vector): VASPDomain { + assert!(vector::length(&domain) <= DOMAIN_LENGTH, errors::invalid_argument(EINVALID_VASP_DOMAIN)); + VASPDomain{ domain } + } + spec create_vasp_domain { + include CreateVASPDomainAbortsIf; + ensures result == VASPDomain { domain }; + } + spec schema CreateVASPDomainAbortsIf { + domain: vector; + aborts_if vector::length(domain) > DOMAIN_LENGTH with errors::INVALID_ARGUMENT; + } + + /// Publish a `VASPDomains` resource under `created` with an empty `domains`. + /// Before VASP Domains, the Treasury Compliance account must send + /// a transaction that invokes `add_vasp_domain` to set the `domains` field with a valid domain + public(friend) fun publish_vasp_domains( + vasp_account: &signer, + ) { + Roles::assert_parent_vasp_role(vasp_account); + assert!( + !exists(signer::address_of(vasp_account)), + errors::already_published(EVASP_DOMAINS) + ); + move_to(vasp_account, VASPDomains { + domains: vector::empty(), + }) + } + spec publish_vasp_domains { + let vasp_addr = signer::address_of(vasp_account); + include Roles::AbortsIfNotParentVasp{account: vasp_account}; + include PublishVASPDomainsAbortsIf; + include PublishVASPDomainsEnsures; + } + spec schema PublishVASPDomainsAbortsIf { + vasp_addr: address; + aborts_if has_vasp_domains(vasp_addr) with errors::ALREADY_PUBLISHED; + } + spec schema PublishVASPDomainsEnsures { + vasp_addr: address; + ensures exists(vasp_addr); + ensures vector::is_empty(global(vasp_addr).domains); + } + + public fun has_vasp_domains(addr: address): bool { + exists(addr) + } + spec has_vasp_domains { + aborts_if false; + ensures result == exists(addr); + } + + /// Publish a `VASPDomainManager` resource under `tc_account` with an empty `vasp_domain_events`. + /// When Treasury Compliance account sends a transaction that invokes either `add_vasp_domain` or + /// `remove_vasp_domain`, a `VASPDomainEvent` is emitted and added to `vasp_domain_events`. + public(friend) fun publish_vasp_domain_manager( + tc_account : &signer, + ) { + Roles::assert_treasury_compliance(tc_account); + assert!( + !exists(signer::address_of(tc_account)), + errors::already_published(EVASP_DOMAIN_MANAGER) + ); + move_to( + tc_account, + VASPDomainManager { + vasp_domain_events: event::new_event_handle(tc_account), + } + ); + } + spec publish_vasp_domain_manager { + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + aborts_if tc_domain_manager_exists() with errors::ALREADY_PUBLISHED; + ensures exists(signer::address_of(tc_account)); + modifies global(signer::address_of(tc_account)); + } + + /// Add a VASPDomain to a parent VASP's VASPDomains resource. + /// When updating VASPDomains, a simple duplicate domain check is done. + /// However, since domains are case insensitive, it is possible by error that two same domains in + /// different lowercase and uppercase format gets added. + public fun add_vasp_domain( + tc_account: &signer, + address: address, + domain: vector, + ) acquires VASPDomainManager, VASPDomains { + Roles::assert_treasury_compliance(tc_account); + assert!(tc_domain_manager_exists(), errors::not_published(EVASP_DOMAIN_MANAGER)); + assert!( + exists(address), + errors::not_published(EVASP_DOMAINS_NOT_PUBLISHED) + ); + + let account_domains = borrow_global_mut(address); + let vasp_domain = create_vasp_domain(domain); + + assert!( + !vector::contains(&account_domains.domains, &vasp_domain), + errors::invalid_argument(EVASP_DOMAIN_ALREADY_EXISTS) + ); + + vector::push_back(&mut account_domains.domains, copy vasp_domain); + + event::emit_event( + &mut borrow_global_mut(@TreasuryCompliance).vasp_domain_events, + VASPDomainEvent { + removed: false, + domain: vasp_domain, + address, + }, + ); + } + spec add_vasp_domain { + include AddVASPDomainAbortsIf; + include AddVASPDomainEnsures; + include AddVASPDomainEmits; + } + spec schema AddVASPDomainAbortsIf { + tc_account: signer; + address: address; + domain: vector; + let domains = global(address).domains; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include CreateVASPDomainAbortsIf; + aborts_if !exists(address) with errors::NOT_PUBLISHED; + aborts_if !tc_domain_manager_exists() with errors::NOT_PUBLISHED; + aborts_if contains(domains, VASPDomain { domain }) with errors::INVALID_ARGUMENT; + } + spec schema AddVASPDomainEnsures { + address: address; + domain: vector; + let post domains = global(address).domains; + ensures contains(domains, VASPDomain { domain }); + } + spec schema AddVASPDomainEmits { + address: address; + domain: vector; + let handle = global(@TreasuryCompliance).vasp_domain_events; + let msg = VASPDomainEvent { + removed: false, + domain: VASPDomain { domain }, + address, + }; + emits msg to handle; + } + + /// Remove a VASPDomain from a parent VASP's VASPDomains resource. + public fun remove_vasp_domain( + tc_account: &signer, + address: address, + domain: vector, + ) acquires VASPDomainManager, VASPDomains { + Roles::assert_treasury_compliance(tc_account); + assert!(tc_domain_manager_exists(), errors::not_published(EVASP_DOMAIN_MANAGER)); + assert!( + exists(address), + errors::not_published(EVASP_DOMAINS_NOT_PUBLISHED) + ); + + let account_domains = borrow_global_mut(address); + let vasp_domain = create_vasp_domain(domain); + + let (has, index) = vector::index_of(&account_domains.domains, &vasp_domain); + if (has) { + vector::remove(&mut account_domains.domains, index); + } else { + abort errors::invalid_argument(EVASP_DOMAIN_NOT_FOUND) + }; + + event::emit_event( + &mut borrow_global_mut(@TreasuryCompliance).vasp_domain_events, + VASPDomainEvent { + removed: true, + domain: vasp_domain, + address: address, + }, + ); + } + spec remove_vasp_domain { + include RemoveVASPDomainAbortsIf; + include RemoveVASPDomainEnsures; + include RemoveVASPDomainEmits; + } + spec schema RemoveVASPDomainAbortsIf { + tc_account: signer; + address: address; + domain: vector; + let domains = global(address).domains; + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + include CreateVASPDomainAbortsIf; + aborts_if !exists(address) with errors::NOT_PUBLISHED; + aborts_if !tc_domain_manager_exists() with errors::NOT_PUBLISHED; + aborts_if !contains(domains, VASPDomain { domain }) with errors::INVALID_ARGUMENT; + } + spec schema RemoveVASPDomainEnsures { + address: address; + domain: vector; + let post domains = global(address).domains; + ensures !contains(domains, VASPDomain { domain }); + } + spec schema RemoveVASPDomainEmits { + tc_account: signer; + address: address; + domain: vector; + let handle = global(@TreasuryCompliance).vasp_domain_events; + let msg = VASPDomainEvent { + removed: true, + domain: VASPDomain { domain }, + address, + }; + emits msg to handle; + } + + public fun has_vasp_domain(addr: address, domain: vector): bool acquires VASPDomains { + assert!( + exists(addr), + errors::not_published(EVASP_DOMAINS_NOT_PUBLISHED) + ); + let account_domains = borrow_global(addr); + let vasp_domain = create_vasp_domain(domain); + vector::contains(&account_domains.domains, &vasp_domain) + } + spec has_vasp_domain { + include HasVASPDomainAbortsIf; + let id_domain = VASPDomain { domain }; + ensures result == contains(global(addr).domains, id_domain); + } + spec schema HasVASPDomainAbortsIf { + addr: address; + domain: vector; + include CreateVASPDomainAbortsIf; + aborts_if !exists(addr) with errors::NOT_PUBLISHED; + } + + public fun tc_domain_manager_exists(): bool { + exists(@TreasuryCompliance) + } + spec tc_domain_manager_exists { + aborts_if false; + ensures result == exists(@TreasuryCompliance); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorAdministrationScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorAdministrationScripts.move new file mode 100644 index 000000000..c54275247 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorAdministrationScripts.move @@ -0,0 +1,553 @@ +address 0x1 { +module ValidatorAdministrationScripts { + use DiemFramework::DiemSystem; + use DiemFramework::SlidingNonce; + use DiemFramework::ValidatorConfig; + use DiemFramework::ValidatorOperatorConfig; + + /// # Summary + /// Adds a validator account to the validator set, and triggers a + /// reconfiguration of the system to admit the account to the validator set for the system. This + /// transaction can only be successfully called by the Diem Root account. + /// + /// # Technical Description + /// This script adds the account at `validator_address` to the validator set. + /// This transaction emits a `DiemConfig::NewEpochEvent` event and triggers a + /// reconfiguration. Once the reconfiguration triggered by this script's + /// execution has been performed, the account at the `validator_address` is + /// considered to be a validator in the network. + /// + /// This transaction script will fail if the `validator_address` address is already in the validator set + /// or does not have a `ValidatorConfig::ValidatorConfig` resource already published under it. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | The signer of the sending account of this transaction. Must be the Diem Root signer. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `validator_name` | `vector` | ASCII-encoded human name for the validator. Must match the human name in the `ValidatorConfig::ValidatorConfig` for the validator. | + /// | `validator_address` | `address` | The validator account address to be added to the validator set. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | 0 | 0 | The provided `validator_name` does not match the already-recorded human name for the validator. | + /// | `Errors::INVALID_ARGUMENT` | `DiemSystem::EINVALID_PROSPECTIVE_VALIDATOR` | The validator to be added does not have a `ValidatorConfig::ValidatorConfig` resource published under it, or its `config` field is empty. | + /// | `Errors::INVALID_ARGUMENT` | `DiemSystem::EALREADY_A_VALIDATOR` | The `validator_address` account is already a registered validator. | + /// | `Errors::INVALID_STATE` | `DiemConfig::EINVALID_BLOCK_TIME` | An invalid time value was encountered in reconfiguration. Unlikely to occur. | + /// | `Errors::LIMIT_EXCEEDED` | `DiemSystem::EMAX_VALIDATORS` | The validator set is already at its maximum size. The validator could not be added. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun add_validator_and_reconfigure( + dr_account: signer, + sliding_nonce: u64, + validator_name: vector, + validator_address: address + ) { + SlidingNonce::record_nonce_or_abort(&dr_account, sliding_nonce); + assert!(ValidatorConfig::get_human_name(validator_address) == validator_name, 0); + DiemSystem::add_validator(&dr_account, validator_address); + } + + + spec add_validator_and_reconfigure { + use DiemFramework::DiemAccount; + use std::errors; + use DiemFramework::Roles; + use DiemFramework::DiemConfig; + + include DiemAccount::TransactionChecks{sender: dr_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{seq_nonce: sliding_nonce, account: dr_account}; + // next is due to abort in get_human_name + include ValidatorConfig::AbortsIfNoValidatorConfig{addr: validator_address}; + // TODO: use an error code from Errors.move instead of 0. + aborts_if ValidatorConfig::get_human_name(validator_address) != validator_name with 0; + include DiemSystem::AddValidatorAbortsIf{validator_addr: validator_address}; + include DiemSystem::AddValidatorEnsures{validator_addr: validator_address}; + + /// Reports INVALID_STATE because of is_operating() and !exists. + /// is_operating() is always true during transactions, and CapabilityHolder is published + /// during initialization (Genesis). + /// Reports REQUIRES_ROLE if dr_account is not Diem root, but that can't happen + /// in practice because it aborts with NOT_PUBLISHED or REQUIRES_ADDRESS, first. + aborts_with [check] + 0, // Odd error code in assert on second statement in add_validator_and_reconfigure + errors::INVALID_ARGUMENT, + errors::NOT_PUBLISHED, + errors::REQUIRES_ADDRESS, + errors::INVALID_STATE, + errors::LIMIT_EXCEEDED, + errors::REQUIRES_ROLE; + + include DiemConfig::ReconfigureEmits; + + /// **Access Control:** + /// Only the Diem Root account can add Validators [[H14]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + } + + /// # Summary + /// Updates a validator's configuration. This does not reconfigure the system and will not update + /// the configuration in the validator set that is seen by other validators in the network. Can + /// only be successfully sent by a Validator Operator account that is already registered with a + /// validator. + /// + /// # Technical Description + /// This updates the fields with corresponding names held in the `ValidatorConfig::ValidatorConfig` + /// config resource held under `validator_account`. It does not emit a `DiemConfig::NewEpochEvent` + /// so the copy of this config held in the validator set will not be updated, and the changes are + /// only "locally" under the `validator_account` account address. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `validator_operator_account` | `signer` | Signer of the sending account. Must be the registered validator operator for the validator at `validator_address`. | + /// | `validator_account` | `address` | The address of the validator's `ValidatorConfig::ValidatorConfig` resource being updated. | + /// | `consensus_pubkey` | `vector` | New Ed25519 public key to be used in the updated `ValidatorConfig::ValidatorConfig`. | + /// | `validator_network_addresses` | `vector` | New set of `validator_network_addresses` to be used in the updated `ValidatorConfig::ValidatorConfig`. | + /// | `fullnode_network_addresses` | `vector` | New set of `fullnode_network_addresses` to be used in the updated `ValidatorConfig::ValidatorConfig`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `ValidatorConfig::EVALIDATOR_CONFIG` | `validator_address` does not have a `ValidatorConfig::ValidatorConfig` resource published under it. | + /// | `Errors::INVALID_ARGUMENT` | `ValidatorConfig::EINVALID_TRANSACTION_SENDER` | `validator_operator_account` is not the registered operator for the validator at `validator_address`. | + /// | `Errors::INVALID_ARGUMENT` | `ValidatorConfig::EINVALID_CONSENSUS_KEY` | `consensus_pubkey` is not a valid ed25519 public key. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun register_validator_config( + validator_operator_account: signer, + // TODO Rename to validator_addr, since it is an address. + validator_account: address, + consensus_pubkey: vector, + validator_network_addresses: vector, + fullnode_network_addresses: vector, + ) { + ValidatorConfig::set_config( + &validator_operator_account, + validator_account, + consensus_pubkey, + validator_network_addresses, + fullnode_network_addresses + ); + } + + /// Access control rule is that only the validator operator for a validator may set + /// call this, but there is an aborts_if in SetConfigAbortsIf that tests that directly. + spec register_validator_config { + use std::errors; + use DiemFramework::DiemAccount; + use std::signer; + + include DiemAccount::TransactionChecks{sender: validator_operator_account}; // properties checked by the prologue. + include ValidatorConfig::SetConfigAbortsIf {validator_addr: validator_account}; + ensures ValidatorConfig::is_valid(validator_account); + + aborts_with [check] + errors::INVALID_ARGUMENT, + errors::NOT_PUBLISHED; + + /// **Access Control:** + /// Only the Validator Operator account which has been registered with the validator can + /// update the validator's configuration [[H15]][PERMISSION]. + aborts_if signer::address_of(validator_operator_account) != + ValidatorConfig::get_operator(validator_account) + with errors::INVALID_ARGUMENT; + } + + /// # Summary + /// This script removes a validator account from the validator set, and triggers a reconfiguration + /// of the system to remove the validator from the system. This transaction can only be + /// successfully called by the Diem Root account. + /// + /// # Technical Description + /// This script removes the account at `validator_address` from the validator set. This transaction + /// emits a `DiemConfig::NewEpochEvent` event. Once the reconfiguration triggered by this event + /// has been performed, the account at `validator_address` is no longer considered to be a + /// validator in the network. This transaction will fail if the validator at `validator_address` + /// is not in the validator set. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | The signer of the sending account of this transaction. Must be the Diem Root signer. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `validator_name` | `vector` | ASCII-encoded human name for the validator. Must match the human name in the `ValidatorConfig::ValidatorConfig` for the validator. | + /// | `validator_address` | `address` | The validator account address to be removed from the validator set. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | The sending account is not the Diem Root account or Treasury Compliance account | + /// | 0 | 0 | The provided `validator_name` does not match the already-recorded human name for the validator. | + /// | `Errors::INVALID_ARGUMENT` | `DiemSystem::ENOT_AN_ACTIVE_VALIDATOR` | The validator to be removed is not in the validator set. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::INVALID_STATE` | `DiemConfig::EINVALID_BLOCK_TIME` | An invalid time value was encountered in reconfiguration. Unlikely to occur. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun remove_validator_and_reconfigure( + dr_account: signer, + sliding_nonce: u64, + validator_name: vector, + validator_address: address + ) { + SlidingNonce::record_nonce_or_abort(&dr_account, sliding_nonce); + // TODO: Use an error code from Errors.move + assert!(ValidatorConfig::get_human_name(validator_address) == validator_name, 0); + DiemSystem::remove_validator(&dr_account, validator_address); + } + + spec remove_validator_and_reconfigure { + use DiemFramework::DiemAccount; + use std::errors; + use DiemFramework::Roles; + use DiemFramework::DiemConfig; + + include DiemAccount::TransactionChecks{sender: dr_account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{seq_nonce: sliding_nonce, account: dr_account}; + // next is due to abort in get_human_name + include ValidatorConfig::AbortsIfNoValidatorConfig{addr: validator_address}; + // TODO: use an error code from Errors.move instead of 0. + aborts_if ValidatorConfig::get_human_name(validator_address) != validator_name with 0; + include DiemSystem::RemoveValidatorAbortsIf{validator_addr: validator_address}; + include DiemSystem::RemoveValidatorEnsures{validator_addr: validator_address}; + + /// Reports INVALID_STATE because of is_operating() and !exists. + /// is_operating() is always true during transactions, and CapabilityHolder is published + /// during initialization (Genesis). + /// Reports REQUIRES_ROLE if dr_account is not Diem root, but that can't happen + /// in practice because it aborts with NOT_PUBLISHED or REQUIRES_ADDRESS, first. + aborts_with [check] + 0, // Odd error code in assert on second statement in add_validator_and_reconfigure + errors::INVALID_ARGUMENT, + errors::NOT_PUBLISHED, + errors::REQUIRES_ADDRESS, + errors::INVALID_STATE, + errors::REQUIRES_ROLE; + + include DiemConfig::ReconfigureEmits; + + /// **Access Control:** + /// Only the Diem Root account can remove Validators [[H14]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + } + + /// # Summary + /// Updates a validator's configuration, and triggers a reconfiguration of the system to update the + /// validator set with this new validator configuration. Can only be successfully sent by a + /// Validator Operator account that is already registered with a validator. + /// + /// # Technical Description + /// This updates the fields with corresponding names held in the `ValidatorConfig::ValidatorConfig` + /// config resource held under `validator_account`. It then emits a `DiemConfig::NewEpochEvent` to + /// trigger a reconfiguration of the system. This reconfiguration will update the validator set + /// on-chain with the updated `ValidatorConfig::ValidatorConfig`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `validator_operator_account` | `signer` | Signer of the sending account. Must be the registered validator operator for the validator at `validator_address`. | + /// | `validator_account` | `address` | The address of the validator's `ValidatorConfig::ValidatorConfig` resource being updated. | + /// | `consensus_pubkey` | `vector` | New Ed25519 public key to be used in the updated `ValidatorConfig::ValidatorConfig`. | + /// | `validator_network_addresses` | `vector` | New set of `validator_network_addresses` to be used in the updated `ValidatorConfig::ValidatorConfig`. | + /// | `fullnode_network_addresses` | `vector` | New set of `fullnode_network_addresses` to be used in the updated `ValidatorConfig::ValidatorConfig`. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `ValidatorConfig::EVALIDATOR_CONFIG` | `validator_address` does not have a `ValidatorConfig::ValidatorConfig` resource published under it. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EVALIDATOR_OPERATOR` | `validator_operator_account` does not have a Validator Operator role. | + /// | `Errors::INVALID_ARGUMENT` | `ValidatorConfig::EINVALID_TRANSACTION_SENDER` | `validator_operator_account` is not the registered operator for the validator at `validator_address`. | + /// | `Errors::INVALID_ARGUMENT` | `ValidatorConfig::EINVALID_CONSENSUS_KEY` | `consensus_pubkey` is not a valid ed25519 public key. | + /// | `Errors::INVALID_STATE` | `DiemConfig::EINVALID_BLOCK_TIME` | An invalid time value was encountered in reconfiguration. Unlikely to occur. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::register_validator_config` + + public entry fun set_validator_config_and_reconfigure( + validator_operator_account: signer, + validator_account: address, + consensus_pubkey: vector, + validator_network_addresses: vector, + fullnode_network_addresses: vector, + ) { + ValidatorConfig::set_config( + &validator_operator_account, + validator_account, + consensus_pubkey, + validator_network_addresses, + fullnode_network_addresses + ); + DiemSystem::update_config_and_reconfigure(&validator_operator_account, validator_account); + } + + spec set_validator_config_and_reconfigure { + use DiemFramework::DiemAccount; + use DiemFramework::DiemConfig; + use DiemFramework::DiemSystem; + use DiemFramework::DiemTimestamp; + use std::errors; + use std::signer; + + // properties checked by the prologue. + include DiemAccount::TransactionChecks{sender: validator_operator_account}; + // UpdateConfigAndReconfigureEnsures includes properties such as not changing info + // for validators in the validator_set other than that for validator_account, etc. + // These properties are important for access control. See notes in DiemSystem. + include DiemSystem::UpdateConfigAndReconfigureEnsures{validator_addr: validator_account}; + ensures ValidatorConfig::is_valid(validator_account); + // The published ValidatorConfig has the correct data, according to the arguments to + // set_validator_config_and_reconfigure + ensures ValidatorConfig::spec_get_config(validator_account) + == ValidatorConfig::Config { + consensus_pubkey, + validator_network_addresses, + fullnode_network_addresses, + }; + + include ValidatorConfig::SetConfigAbortsIf{validator_addr: validator_account}; + include DiemSystem::UpdateConfigAndReconfigureAbortsIf{validator_addr: validator_account}; + + // Reconfiguration only happens if validator info changes for a validator in the validator set. + // v_info.config is the old config (if it exists) and the Config with args from set_config is + // the new config + let is_validator_info_updated = + (exists v_info in DiemSystem::spec_get_validators(): + v_info.addr == validator_account + && v_info.config != ValidatorConfig::Config { + consensus_pubkey, + validator_network_addresses, + fullnode_network_addresses, + }); + include is_validator_info_updated ==> DiemConfig::ReconfigureAbortsIf; + let validator_index = DiemSystem::spec_index_of_validator(DiemSystem::spec_get_validators(), validator_account); + let last_config_time = DiemSystem::spec_get_validators()[validator_index].last_config_update_time; + aborts_if is_validator_info_updated && last_config_time > DiemSystem::MAX_U64 - DiemSystem::FIVE_MINUTES + with errors::LIMIT_EXCEEDED; + aborts_if is_validator_info_updated && DiemTimestamp::spec_now_microseconds() <= last_config_time + DiemSystem::FIVE_MINUTES + with errors::LIMIT_EXCEEDED; + + /// This reports a possible INVALID_STATE abort, which comes from an assert in DiemConfig::reconfigure_ + /// that config.last_reconfiguration_time is not in the future. This is a system error that a user + /// for which there is no useful recovery except to resubmit the transaction. + aborts_with [check] + errors::NOT_PUBLISHED, + errors::REQUIRES_ROLE, + errors::INVALID_ARGUMENT, + errors::INVALID_STATE; + + include is_validator_info_updated ==> DiemConfig::ReconfigureEmits; + + /// **Access Control:** + /// Only the Validator Operator account which has been registered with the validator can + /// update the validator's configuration [[H15]][PERMISSION]. + aborts_if signer::address_of(validator_operator_account) != + ValidatorConfig::get_operator(validator_account) + with errors::INVALID_ARGUMENT; + } + + /// # Summary + /// Sets the validator operator for a validator in the validator's configuration resource "locally" + /// and does not reconfigure the system. Changes from this transaction will not picked up by the + /// system until a reconfiguration of the system is triggered. May only be sent by an account with + /// Validator role. + /// + /// # Technical Description + /// Sets the account at `operator_account` address and with the specified `human_name` as an + /// operator for the sending validator account. The account at `operator_account` address must have + /// a Validator Operator role and have a `ValidatorOperatorConfig::ValidatorOperatorConfig` + /// resource published under it. The sending `account` must be a Validator and have a + /// `ValidatorConfig::ValidatorConfig` resource published under it. This script does not emit a + /// `DiemConfig::NewEpochEvent` and no reconfiguration of the system is initiated by this script. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | The signer of the sending account of the transaction. | + /// | `operator_name` | `vector` | Validator operator's human name. | + /// | `operator_account` | `address` | Address of the validator operator account to be added as the `account` validator's operator. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `ValidatorOperatorConfig::EVALIDATOR_OPERATOR_CONFIG` | The `ValidatorOperatorConfig::ValidatorOperatorConfig` resource is not published under `operator_account`. | + /// | 0 | 0 | The `human_name` field of the `ValidatorOperatorConfig::ValidatorOperatorConfig` resource under `operator_account` does not match the provided `human_name`. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EVALIDATOR` | `account` does not have a Validator account role. | + /// | `Errors::INVALID_ARGUMENT` | `ValidatorConfig::ENOT_A_VALIDATOR_OPERATOR` | The account at `operator_account` does not have a `ValidatorOperatorConfig::ValidatorOperatorConfig` resource. | + /// | `Errors::NOT_PUBLISHED` | `ValidatorConfig::EVALIDATOR_CONFIG` | A `ValidatorConfig::ValidatorConfig` is not published under `account`. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun set_validator_operator( + account: signer, + operator_name: vector, + operator_account: address + ) { + assert!(ValidatorOperatorConfig::get_human_name(operator_account) == operator_name, 0); + ValidatorConfig::set_operator(&account, operator_account); + } + + spec set_validator_operator { + use DiemFramework::DiemAccount; + use std::signer; + use std::errors; + use DiemFramework::Roles; + + let account_addr = signer::address_of(account); + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + // next is due to abort in get_human_name + include ValidatorConfig::AbortsIfNoValidatorConfig{addr: account_addr}; + // TODO: use an error code from Errors.move instead of 0. + aborts_if ValidatorOperatorConfig::get_human_name(operator_account) != operator_name with 0; + include ValidatorConfig::SetOperatorAbortsIf{validator_account: account, operator_addr: operator_account}; + include ValidatorConfig::SetOperatorEnsures{validator_account: account, operator_addr: operator_account}; + + /// Reports INVALID_STATE because of !exists, but that can't happen + /// because CapabilityHolder is published during initialization (Genesis). + aborts_with [check] + 0, // Odd error code in assert on second statement in add_validator_and_reconfigure + errors::INVALID_ARGUMENT, + errors::NOT_PUBLISHED, + errors::REQUIRES_ROLE; + + /// **Access Control:** + /// Only a Validator account can set its Validator Operator [[H16]][PERMISSION]. + include Roles::AbortsIfNotValidator; + } + + /// # Summary + /// Sets the validator operator for a validator in the validator's configuration resource "locally" + /// and does not reconfigure the system. Changes from this transaction will not picked up by the + /// system until a reconfiguration of the system is triggered. May only be sent by the Diem Root + /// account as a write set transaction. + /// + /// # Technical Description + /// Sets the account at `operator_account` address and with the specified `human_name` as an + /// operator for the validator `account`. The account at `operator_account` address must have a + /// Validator Operator role and have a `ValidatorOperatorConfig::ValidatorOperatorConfig` resource + /// published under it. The account represented by the `account` signer must be a Validator and + /// have a `ValidatorConfig::ValidatorConfig` resource published under it. No reconfiguration of + /// the system is initiated by this script. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | Signer of the sending account of the write set transaction. May only be the Diem Root signer. | + /// | `account` | `signer` | Signer of account specified in the `execute_as` field of the write set transaction. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction for Diem Root. | + /// | `operator_name` | `vector` | Validator operator's human name. | + /// | `operator_account` | `address` | Address of the validator operator account to be added as the `account` validator's operator. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` in `dr_account` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` in `dr_account` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` in` dr_account` has been previously recorded. | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | The sending account is not the Diem Root account or Treasury Compliance account | + /// | `Errors::NOT_PUBLISHED` | `ValidatorOperatorConfig::EVALIDATOR_OPERATOR_CONFIG` | The `ValidatorOperatorConfig::ValidatorOperatorConfig` resource is not published under `operator_account`. | + /// | 0 | 0 | The `human_name` field of the `ValidatorOperatorConfig::ValidatorOperatorConfig` resource under `operator_account` does not match the provided `human_name`. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EVALIDATOR` | `account` does not have a Validator account role. | + /// | `Errors::INVALID_ARGUMENT` | `ValidatorConfig::ENOT_A_VALIDATOR_OPERATOR` | The account at `operator_account` does not have a `ValidatorOperatorConfig::ValidatorOperatorConfig` resource. | + /// | `Errors::NOT_PUBLISHED` | `ValidatorConfig::EVALIDATOR_CONFIG` | A `ValidatorConfig::ValidatorConfig` is not published under `account`. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun set_validator_operator_with_nonce_admin( + dr_account: signer, + account: signer, + sliding_nonce: u64, + operator_name: vector, + operator_account: address + ) { + SlidingNonce::record_nonce_or_abort(&dr_account, sliding_nonce); + assert!(ValidatorOperatorConfig::get_human_name(operator_account) == operator_name, 0); + ValidatorConfig::set_operator(&account, operator_account); + } + + spec set_validator_operator_with_nonce_admin { + use DiemFramework::DiemAccount; + use std::signer; + use std::errors; + use DiemFramework::Roles; + + let account_addr = signer::address_of(account); + include DiemAccount::TransactionChecks{sender: account}; // properties checked by the prologue. + include SlidingNonce::RecordNonceAbortsIf{seq_nonce: sliding_nonce, account: dr_account}; + // next is due to abort in get_human_name + include ValidatorConfig::AbortsIfNoValidatorConfig{addr: account_addr}; + // TODO: use an error code from Errors.move instead of 0. + aborts_if ValidatorOperatorConfig::get_human_name(operator_account) != operator_name with 0; + include ValidatorConfig::SetOperatorAbortsIf{validator_account: account, operator_addr: operator_account}; + include ValidatorConfig::SetOperatorEnsures{validator_account: account, operator_addr: operator_account}; + + aborts_with [check] + 0, // Odd error code in assert on second statement in add_validator_and_reconfigure + errors::INVALID_ARGUMENT, + errors::NOT_PUBLISHED, + errors::REQUIRES_ROLE; + + /// **Access Control:** + /// Only the Diem Root account can process the admin scripts [[H9]][PERMISSION]. + requires Roles::has_diem_root_role(dr_account); /// This is ensured by DiemAccount::writeset_prologue. + /// Only a Validator account can set its Validator Operator [[H16]][PERMISSION]. + include Roles::AbortsIfNotValidator; + } +} +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorConfig.move new file mode 100644 index 000000000..d57640276 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorConfig.move @@ -0,0 +1,362 @@ +/// The ValidatorConfig resource holds information about a validator. Information +/// is published and updated by Diem root in a `Self::ValidatorConfig` in preparation for +/// later inclusion (by functions in DiemConfig) in a `DiemConfig::DiemConfig` +/// struct (the `Self::ValidatorConfig` in a `DiemConfig::ValidatorInfo` which is a member +/// of the `DiemSystem::DiemSystem.validators` vector). +module DiemFramework::ValidatorConfig { + use DiemFramework::DiemTimestamp; + use std::errors; + use DiemFramework::Signature; + use DiemFramework::Roles; + use DiemFramework::ValidatorOperatorConfig; + use std::option::{Self, Option}; + use std::signer; + friend DiemFramework::DiemAccount; + + #[test_only] + friend DiemFramework::ValidatorConfigTests; + + struct Config has copy, drop, store { + consensus_pubkey: vector, + validator_network_addresses: vector, + fullnode_network_addresses: vector, + } + + struct ValidatorConfig has key { + /// set and rotated by the operator_account + config: Option, + operator_account: Option
, + /// The human readable name of this entity. Immutable. + human_name: vector, + } + + // TODO(valerini): add events here + + /// The `ValidatorConfig` resource was not in the required state + const EVALIDATOR_CONFIG: u64 = 0; + /// The sender is not the operator for the specified validator + const EINVALID_TRANSACTION_SENDER: u64 = 1; + /// The provided consensus public key is malformed + const EINVALID_CONSENSUS_KEY: u64 = 2; + /// Tried to set an account without the correct operator role as a Validator Operator + const ENOT_A_VALIDATOR_OPERATOR: u64 = 3; + + /////////////////////////////////////////////////////////////////////////// + // Validator setup methods + /////////////////////////////////////////////////////////////////////////// + + /// Publishes a mostly empty ValidatorConfig struct. Eventually, it + /// will have critical info such as keys, network addresses for validators, + /// and the address of the validator operator. + public(friend) fun publish( + validator_account: &signer, + dr_account: &signer, + human_name: vector, + ) { + DiemTimestamp::assert_operating(); + Roles::assert_diem_root(dr_account); + Roles::assert_validator(validator_account); + assert!( + !exists(signer::address_of(validator_account)), + errors::already_published(EVALIDATOR_CONFIG) + ); + move_to(validator_account, ValidatorConfig { + config: option::none(), + operator_account: option::none(), + human_name, + }); + } + + spec publish { + include PublishAbortsIf; + ensures exists_config(signer::address_of(validator_account)); + } + + spec schema PublishAbortsIf { + validator_account: signer; + dr_account: signer; + let validator_addr = signer::address_of(validator_account); + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include Roles::AbortsIfNotValidator{account: validator_account}; + aborts_if exists_config(validator_addr) + with errors::ALREADY_PUBLISHED; + } + + /// Returns true if a ValidatorConfig resource exists under addr. + fun exists_config(addr: address): bool { + exists(addr) + } + + /// Describes abort if ValidatorConfig does not exist. + spec schema AbortsIfNoValidatorConfig { + addr: address; + aborts_if !exists_config(addr) with errors::NOT_PUBLISHED; + } + + /////////////////////////////////////////////////////////////////////////// + // Rotation methods callable by ValidatorConfig owner + /////////////////////////////////////////////////////////////////////////// + + /// Sets a new operator account, preserving the old config. + /// Note: Access control. No one but the owner of the account may change .operator_account + public fun set_operator(validator_account: &signer, operator_addr: address) acquires ValidatorConfig { + Roles::assert_validator(validator_account); + // Check for validator role is not necessary since the role is checked when the config + // resource is published. + assert!( + ValidatorOperatorConfig::has_validator_operator_config(operator_addr), + errors::invalid_argument(ENOT_A_VALIDATOR_OPERATOR) + ); + let sender = signer::address_of(validator_account); + assert!(exists_config(sender), errors::not_published(EVALIDATOR_CONFIG)); + (borrow_global_mut(sender)).operator_account = option::some(operator_addr); + } + spec set_operator { + /// Must abort if the signer does not have the Validator role [[H16]][PERMISSION]. + include Roles::AbortsIfNotValidator{account: validator_account}; + include SetOperatorAbortsIf; + include SetOperatorEnsures; + } + + spec schema SetOperatorAbortsIf { + /// Must abort if the signer does not have the Validator role [B24]. + validator_account: signer; + operator_addr: address; + let validator_addr = signer::address_of(validator_account); + include Roles::AbortsIfNotValidator{account: validator_account}; + aborts_if !ValidatorOperatorConfig::has_validator_operator_config(operator_addr) + with errors::INVALID_ARGUMENT; + include AbortsIfNoValidatorConfig{addr: validator_addr}; + aborts_if !ValidatorOperatorConfig::has_validator_operator_config(operator_addr) with errors::NOT_PUBLISHED; + } + + spec schema SetOperatorEnsures { + validator_account: signer; + operator_addr: address; + let validator_addr = signer::address_of(validator_account); + ensures spec_has_operator(validator_addr); + ensures get_operator(validator_addr) == operator_addr; + /// The signer can only change its own operator account [[H16]][PERMISSION]. + ensures forall addr: address where addr != validator_addr: + global(addr).operator_account == old(global(addr).operator_account); + } + + /// Removes an operator account, setting a corresponding field to Option::none. + /// The old config is preserved. + public fun remove_operator(validator_account: &signer) acquires ValidatorConfig { + Roles::assert_validator(validator_account); + let sender = signer::address_of(validator_account); + // Config field remains set + assert!(exists_config(sender), errors::not_published(EVALIDATOR_CONFIG)); + (borrow_global_mut(sender)).operator_account = option::none(); + } + + spec remove_operator { + /// Must abort if the signer does not have the Validator role [[H16]][PERMISSION]. + let sender = signer::address_of(validator_account); + include Roles::AbortsIfNotValidator{account: validator_account}; + include AbortsIfNoValidatorConfig{addr: sender}; + ensures !spec_has_operator(signer::address_of(validator_account)); + + /// The signer can only change its own operator account [[H16]][PERMISSION]. + ensures forall addr: address where addr != sender: + global(addr).operator_account == old(global(addr).operator_account); + } + + /////////////////////////////////////////////////////////////////////////// + // Rotation methods callable by ValidatorConfig.operator_account + /////////////////////////////////////////////////////////////////////////// + + /// Rotate the config in the validator_account. + /// Once the config is set, it can not go back to `Option::none` - this is crucial for validity + /// of the DiemSystem's code. + public fun set_config( + validator_operator_account: &signer, + validator_addr: address, + consensus_pubkey: vector, + validator_network_addresses: vector, + fullnode_network_addresses: vector, + ) acquires ValidatorConfig { + assert!( + signer::address_of(validator_operator_account) == get_operator(validator_addr), + errors::invalid_argument(EINVALID_TRANSACTION_SENDER) + ); + assert!( + Signature::ed25519_validate_pubkey(copy consensus_pubkey), + errors::invalid_argument(EINVALID_CONSENSUS_KEY) + ); + // TODO(valerini): verify the proof of posession for consensus_pubkey + assert!(exists_config(validator_addr), errors::not_published(EVALIDATOR_CONFIG)); + let t_ref = borrow_global_mut(validator_addr); + t_ref.config = option::some(Config { + consensus_pubkey, + validator_network_addresses, + fullnode_network_addresses, + }); + } + spec set_config { + pragma opaque; + modifies global(validator_addr); + include SetConfigAbortsIf; + ensures is_valid(validator_addr); + ensures global(validator_addr) + == update_field(old(global(validator_addr)), + config, + option::spec_some(Config { + consensus_pubkey, + validator_network_addresses, + fullnode_network_addresses, + })); + } + spec schema SetConfigAbortsIf { + validator_operator_account: signer; + validator_addr: address; + consensus_pubkey: vector; + aborts_if signer::address_of(validator_operator_account) != get_operator(validator_addr) + with errors::INVALID_ARGUMENT; + include AbortsIfGetOperator{addr: validator_addr}; + aborts_if !Signature::ed25519_validate_pubkey(consensus_pubkey) with errors::INVALID_ARGUMENT; + } + + /////////////////////////////////////////////////////////////////////////// + // Publicly callable APIs: getters + /////////////////////////////////////////////////////////////////////////// + + /// Returns true if all of the following is true: + /// 1) there is a ValidatorConfig resource under the address, and + /// 2) the config is set, and + /// we do not require the operator_account to be set to make sure + /// that if the validator account becomes valid, it stays valid, e.g. + /// all validators in the Validator Set are valid + public fun is_valid(addr: address): bool acquires ValidatorConfig { + exists(addr) && option::is_some(&borrow_global(addr).config) + } + + spec is_valid { + pragma opaque; + aborts_if false; + ensures result == is_valid(addr); + } + + /// Get Config + /// Aborts if there is no ValidatorConfig resource or if its config is empty + public fun get_config(addr: address): Config acquires ValidatorConfig { + assert!(exists_config(addr), errors::not_published(EVALIDATOR_CONFIG)); + let config = &borrow_global(addr).config; + assert!(option::is_some(config), errors::invalid_argument(EVALIDATOR_CONFIG)); + *option::borrow(config) + } + + spec get_config { + pragma opaque; + include AbortsIfNoValidatorConfig; + aborts_if option::is_none(global(addr).config) with errors::INVALID_ARGUMENT; + ensures result == spec_get_config(addr); + } + + /// Returns the config published under addr. + spec fun spec_get_config(addr: address): Config { + option::borrow(global(addr).config) + } + + /// Get validator's account human name + /// Aborts if there is no ValidatorConfig resource + public fun get_human_name(addr: address): vector acquires ValidatorConfig { + assert!(exists(addr), errors::not_published(EVALIDATOR_CONFIG)); + let t_ref = borrow_global(addr); + *&t_ref.human_name + } + + spec get_human_name { + pragma opaque; + include AbortsIfNoValidatorConfig; + ensures result == get_human_name(addr); + } + + /// Get operator's account + /// Aborts if there is no ValidatorConfig resource or + /// if the operator_account is unset + public fun get_operator(addr: address): address acquires ValidatorConfig { + assert!(exists(addr), errors::not_published(EVALIDATOR_CONFIG)); + let t_ref = borrow_global(addr); + assert!(option::is_some(&t_ref.operator_account), errors::invalid_argument(EVALIDATOR_CONFIG)); + *option::borrow(&t_ref.operator_account) + } + + spec get_operator { + pragma opaque; + include AbortsIfGetOperator; + ensures result == get_operator(addr); + } + + spec schema AbortsIfGetOperator { + addr: address; + include AbortsIfNoValidatorConfig; + aborts_if !spec_has_operator(addr) with errors::INVALID_ARGUMENT; + } + + /// Get consensus_pubkey from Config + /// Never aborts + public fun get_consensus_pubkey(config_ref: &Config): &vector { + &config_ref.consensus_pubkey + } + + /// Get validator's network address from Config + /// Never aborts + public fun get_validator_network_addresses(config_ref: &Config): &vector { + &config_ref.validator_network_addresses + } + + spec module {} // Switch documentation context to module level. + + spec module { + pragma aborts_if_is_strict; + } + + /// # Access Control + + /// The permission "{Set,Remove}ValidatorOperator(addr)" is granted to Validator [[H16]][PERMISSION] + spec module { + invariant update forall a: address where old(exists(a)) && exists(a): + old(global(a).operator_account) != global(a).operator_account + ==> signer::is_txn_signer_addr(a) && Roles::spec_has_validator_role_addr(a); + } + + /// # Validity of Validators + + /// See comment on `ValidatorConfig::set_config` -- DiemSystem depends on this. + spec module { + /// A validator stays valid once it becomes valid. + invariant update + forall validator: address where old(is_valid(validator)): is_valid(validator); + } + + /// # Consistency Between Resources and Roles + + spec module { + + /// Every address that has a ValidatorConfig also has a validator role. + invariant forall addr: address where exists_config(addr): + Roles::spec_has_validator_role_addr(addr); + + /// DIP-6 Property: If address has a ValidatorConfig, it has a validator role. This invariant is useful + /// in DiemSystem so we don't have to check whether every validator address has a validator role. + invariant forall addr: address where exists_config(addr): + Roles::spec_has_validator_role_addr(addr); + + /// DIP-6 Property: Every address that is_valid (meaning it has a ValidatorConfig with + /// a config option that is "some") has a validator role. This is a trivial consequence + /// of the previous invariant, but it is not inductive and can't be proved without the + /// previous one as a helper. + invariant forall addr: address where is_valid(addr): + Roles::spec_has_validator_role_addr(addr); + } + + /// # Helper Function + + /// Returns true if addr has an operator account. + spec fun spec_has_operator(addr: address): bool { + option::is_some(global(addr).operator_account) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorOperatorConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorOperatorConfig.move new file mode 100644 index 000000000..b843a9790 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/ValidatorOperatorConfig.move @@ -0,0 +1,92 @@ +/// Stores the string name of a ValidatorOperator account. +module DiemFramework::ValidatorOperatorConfig { + use std::errors; + use std::signer; + use DiemFramework::Roles; + use DiemFramework::DiemTimestamp; + friend DiemFramework::DiemAccount; + + #[test_only] + friend DiemFramework::ValidatorOperatorConfigTests; + + #[test_only] + friend DiemFramework::ValidatorConfigTests; + + struct ValidatorOperatorConfig has key { + /// The human readable name of this entity. Immutable. + human_name: vector, + } + + /// The `ValidatorOperatorConfig` was not in the required state + const EVALIDATOR_OPERATOR_CONFIG: u64 = 0; + + public(friend) fun publish( + validator_operator_account: &signer, + dr_account: &signer, + human_name: vector, + ) { + DiemTimestamp::assert_operating(); + Roles::assert_diem_root(dr_account); + Roles::assert_validator_operator(validator_operator_account); + assert!( + !has_validator_operator_config(signer::address_of(validator_operator_account)), + errors::already_published(EVALIDATOR_OPERATOR_CONFIG) + ); + + move_to(validator_operator_account, ValidatorOperatorConfig { + human_name, + }); + } + spec publish { + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include Roles::AbortsIfNotValidatorOperator{account: validator_operator_account}; + include PublishAbortsIf; + ensures has_validator_operator_config(signer::address_of(validator_operator_account)); + } + + spec schema PublishAbortsIf { + validator_operator_account: signer; + dr_account: signer; + let validator_operator_addr = signer::address_of(validator_operator_account); + include DiemTimestamp::AbortsIfNotOperating; + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + include Roles::AbortsIfNotValidatorOperator{account: validator_operator_account}; + aborts_if has_validator_operator_config(validator_operator_addr) + with errors::ALREADY_PUBLISHED; + } + + /// Get validator's account human name + /// Aborts if there is no ValidatorOperatorConfig resource + public fun get_human_name(validator_operator_addr: address): vector acquires ValidatorOperatorConfig { + assert!(has_validator_operator_config(validator_operator_addr), errors::not_published(EVALIDATOR_OPERATOR_CONFIG)); + *&borrow_global(validator_operator_addr).human_name + } + spec get_human_name { + pragma opaque; + aborts_if !has_validator_operator_config(validator_operator_addr) with errors::NOT_PUBLISHED; + ensures result == get_human_name(validator_operator_addr); + } + public fun has_validator_operator_config(validator_operator_addr: address): bool { + exists(validator_operator_addr) + } + spec has_validator_operator_config { + ensures result == has_validator_operator_config(validator_operator_addr); + } + + spec module {} // switch documentation context back to module level + + /// # Consistency Between Resources and Roles + + /// If an address has a ValidatorOperatorConfig resource, it has a validator operator role. + spec module { + invariant forall addr: address where has_validator_operator_config(addr): + Roles::spec_has_validator_operator_role_addr(addr); + } + + /// # Persistence + spec module { + invariant update forall addr: address where old(exists(addr)): + exists(addr); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/XDX.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/XDX.move new file mode 100644 index 000000000..5b73edcf7 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/XDX.move @@ -0,0 +1,177 @@ +/// NB: This module is a stub of the `XDX` at the moment. +/// +/// Once the component makeup of the XDX has been chosen the +/// `Reserve` will be updated to hold the backing coins in the correct ratios. + +module DiemFramework::XDX { + use DiemFramework::AccountLimits; + use DiemFramework::CoreAddresses; + use std::errors; + use std::fixed_point32; + use DiemFramework::Diem; + use DiemFramework::DiemTimestamp; + + /// The type tag representing the `XDX` currency on-chain. + struct XDX { } + + /// Note: Currently only holds the mint, burn, and preburn capabilities for + /// XDX. Once the makeup of the XDX has been determined this resource will + /// be updated to hold the backing XDX reserve compnents on-chain. + /// + /// The on-chain reserve for the `XDX` holds both the capability for minting `XDX` + /// coins, and also each reserve component that holds the backing for these coins on-chain. + /// Currently this holds no coins since XDX is not able to be minted/created. + struct Reserve has key { + /// The mint capability allowing minting of `XDX` coins. + mint_cap: Diem::MintCapability, + /// The burn capability for `XDX` coins. This is used for the unpacking + /// of `XDX` coins into the underlying backing currencies. + burn_cap: Diem::BurnCapability, + /// The preburn for `XDX`. This is an administrative field since we + /// need to alway preburn before we burn. + preburn_cap: Diem::Preburn, + // TODO: Once the reserve has been determined this resource will + // contain a ReserveComponent for every currency that makes + // up the reserve. + } + + /// The `Reserve` resource is in an invalid state + const ERESERVE: u64 = 0; + + /// Initializes the `XDX` module. This sets up the initial `XDX` ratios and + /// reserve components, and creates the mint, preburn, and burn + /// capabilities for `XDX` coins. The `XDX` currency must not already be + /// registered in order for this to succeed. The sender must both be the + /// correct address (`@CurrencyInfo`) and have the + /// correct permissions (`&Capability`). Both of these + /// restrictions are enforced in the `Diem::register_currency` function, but also enforced here. + public fun initialize( + dr_account: &signer, + tc_account: &signer, + ) { + DiemTimestamp::assert_genesis(); + // Operational constraint + CoreAddresses::assert_currency_info(dr_account); + // Reserve must not exist. + assert!(!exists(@DiemRoot), errors::already_published(ERESERVE)); + let (mint_cap, burn_cap) = Diem::register_currency( + dr_account, + fixed_point32::create_from_rational(1, 1), // exchange rate to XDX + true, // is_synthetic + 1000000, // scaling_factor = 10^6 + 1000, // fractional_part = 10^3 + b"XDX" + ); + // XDX cannot be minted. + Diem::update_minting_ability(tc_account, false); + AccountLimits::publish_unrestricted_limits(dr_account); + let preburn_cap = Diem::create_preburn(tc_account); + move_to(dr_account, Reserve { mint_cap, burn_cap, preburn_cap }); + } + spec initialize { + use DiemFramework::Roles; + include CoreAddresses::AbortsIfNotCurrencyInfo{account: dr_account}; + aborts_if exists(@DiemRoot) with errors::ALREADY_PUBLISHED; + include Diem::RegisterCurrencyAbortsIf{ + currency_code: b"XDX", + scaling_factor: 1000000 + }; + include AccountLimits::PublishUnrestrictedLimitsAbortsIf{publish_account: dr_account}; + + include Diem::RegisterCurrencyEnsures{ + to_xdx_exchange_rate: fixed_point32::spec_create_from_rational(1, 1), + is_synthetic: true, + fractional_part: 1000 + }; + + include Diem::UpdateMintingAbilityEnsures{can_mint: false}; + include AccountLimits::PublishUnrestrictedLimitsEnsures{publish_account: dr_account}; + ensures exists(@DiemRoot); + + /// Registering XDX can only be done in genesis. + include DiemTimestamp::AbortsIfNotGenesis; + /// Only the DiemRoot account can register a new currency [[H8]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + /// Only the TreasuryCompliance role can update the `can_mint` field of CurrencyInfo [[H2]][PERMISSION]. + /// Moreover, only the TreasuryCompliance role can create Preburn. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + } + + /// Returns true if `CoinType` is `XDX::XDX` + public fun is_xdx(): bool { + Diem::is_currency() && + Diem::currency_code() == Diem::currency_code() + } + spec is_xdx { + pragma opaque; + include Diem::spec_is_currency() ==> Diem::AbortsIfNoCurrency; + ensures result == spec_is_xdx(); + } + spec fun spec_is_xdx(): bool { + Diem::spec_is_currency() && Diem::spec_is_currency() && + (Diem::spec_currency_code() == Diem::spec_currency_code()) + } + + /// Return the account address where the globally unique XDX::Reserve resource is stored + public fun reserve_address(): address { + @CurrencyInfo + } + + // ================================================================= + // Module Specification + + spec module {} // switch documentation context back to module level + + /// # Persistence of Resources + + spec module { + /// After genesis, the Reserve resource exists. + invariant [suspendable] DiemTimestamp::is_operating() ==> reserve_exists(); + + /// After genesis, XDX is registered. + invariant [suspendable] DiemTimestamp::is_operating() ==> Diem::is_currency(); + + /// After genesis, the exchange rate to XDX is always equal to 1.0. + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::spec_xdx_exchange_rate() == fixed_point32::spec_create_from_rational(1, 1); + + /// After genesis, XDX is always a synthetic currency. + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::is_synthetic_currency(); + + /// After genesis, the scaling factor for XDX is always equal to 1,000,000. + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::spec_currency_info().scaling_factor == 1000000; + + /// After genesis, the fractional part for XDX is always equal to 1,000. + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::spec_currency_info().fractional_part == 1000; + + /// After genesis, the currency code for XDX is always "XDX". + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::spec_currency_code() == b"XDX"; + } + + /// # Helper Functions + spec module { + /// Checks whether the Reserve resource exists. + fun reserve_exists(): bool { + exists(reserve_address()) + } + + /// After genesis, `LimitsDefinition` is published at Diem root. It's published by + /// AccountLimits::publish_unrestricted_limits, but we can't prove the condition there because + /// it does not hold for all types (but does hold for XDX). + invariant [suspendable] DiemTimestamp::is_operating() + ==> exists>(@DiemRoot); + + /// `LimitsDefinition` is not published at any other address + invariant [suspendable] forall addr: address where exists>(addr): + addr == @DiemRoot; + + /// `Reserve` is persistent + invariant update old(reserve_exists()) + ==> reserve_exists(); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/XUS.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/XUS.move new file mode 100644 index 000000000..16976c9ac --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/sources/XUS.move @@ -0,0 +1,187 @@ +/// This module defines the coin type XUS and its initialization function. +module DiemFramework::XUS { + use DiemFramework::AccountLimits; + use DiemFramework::Diem; + use DiemFramework::DiemTimestamp; + use DiemFramework::Roles; + use std::fixed_point32; + + /// The type tag representing the `XUS` currency on-chain. + struct XUS { } + + /// Registers the `XUS` cointype. This can only be called from genesis. + public fun initialize( + dr_account: &signer, + tc_account: &signer, + ) { + DiemTimestamp::assert_genesis(); + Roles::assert_treasury_compliance(tc_account); + Roles::assert_diem_root(dr_account); + Diem::register_SCS_currency( + dr_account, + tc_account, + fixed_point32::create_from_rational(1, 1), // exchange rate to XDX + 1000000, // scaling_factor = 10^6 + 100, // fractional_part = 10^2 + b"XUS" + ); + AccountLimits::publish_unrestricted_limits(dr_account); + } + spec initialize { + use DiemFramework::Roles; + include Diem::RegisterSCSCurrencyAbortsIf{ + currency_code: b"XUS", + scaling_factor: 1000000, + }; + include AccountLimits::PublishUnrestrictedLimitsAbortsIf{publish_account: dr_account}; + include Diem::RegisterSCSCurrencyEnsures{ + to_xdx_exchange_rate: fixed_point32::spec_create_from_rational(1, 1), + fractional_part: 100 + }; + include AccountLimits::PublishUnrestrictedLimitsEnsures{publish_account: dr_account}; + /// Registering XUS can only be done in genesis. + include DiemTimestamp::AbortsIfNotGenesis; + /// Only the DiemRoot account can register a new currency [[H8]][PERMISSION]. + include Roles::AbortsIfNotDiemRoot{account: dr_account}; + /// Only a TreasuryCompliance account can have the MintCapability [[H1]][PERMISSION]. + /// Moreover, only a TreasuryCompliance account can have the BurnCapability [[H3]][PERMISSION]. + include Roles::AbortsIfNotTreasuryCompliance{account: tc_account}; + } + + // ================================================================= + // Module Specification + + spec module {} // Switch to module documentation context + + /// # Persistence of Resources + spec module { + /// After genesis, XUS is registered. + invariant [suspendable] DiemTimestamp::is_operating() ==> Diem::is_currency(); + + /// After genesis, `LimitsDefinition` is published at Diem root. It's published by + /// AccountLimits::publish_unrestricted_limits, but we can't prove the condition there because + /// it does not hold for all types (but does hold for XUS). + invariant [suspendable] DiemTimestamp::is_operating() + ==> exists>(@DiemRoot); + + /// `LimitsDefinition` is not published at any other address + invariant [suspendable] forall addr: address where exists>(addr): + addr == @DiemRoot; + + /// After genesis, XUS is always a non-synthetic currency. + invariant [suspendable] DiemTimestamp::is_operating() + ==> !Diem::is_synthetic_currency(); + + /// After genesis, the scaling factor for XUS is always equal to 1,000,000. + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::spec_currency_info().scaling_factor == 1000000; + + /// After genesis, the fractional part for XUS is always equal to 100. + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::spec_currency_info().fractional_part == 100; + + /// After genesis, the currency code for XUS is always "XUS". + invariant [suspendable] DiemTimestamp::is_operating() + ==> Diem::spec_currency_code() == b"XUS"; + } + + /// # Access Control + + /// ## Minting + + spec module { + /// Only TreasuryCompliance can have MintCapability [[H1]][PERMISSION]. + /// If an account has MintCapability, it is a TreasuryCompliance account. + invariant + forall a: address: + Diem::spec_has_mint_capability(a) ==> + Roles::spec_has_treasury_compliance_role_addr(a); + + /// Only the owner of MintCapability can mint XUS [[H1]][PERMISSION]. + /// If the `total_value` for XUS is increased, the transaction should be + /// signed by the owner of MintCapability. + invariant update [suspendable] ( + old(Diem::spec_is_currency()) && + Diem::spec_is_currency() && + old(Diem::spec_currency_info().total_value) < Diem::spec_currency_info().total_value + ) ==> Diem::spec_signed_by_mint_capability_owner(); + + /// The permission to mint XUS is unique [[I1]][PERMISSION]. + /// At most one address has a MintCapability. + invariant + forall a1: address, a2: address: + (Diem::spec_has_mint_capability(a1) && Diem::spec_has_mint_capability(a2)) ==> a1 == a2; + + /// MintCapability is not transferrable [[J1]][PERMISSION]. + /// MintCapability is not copiable, and once it's published, it's not removed. + invariant update + forall a: address + where old(exists>(a)): + exists>(a); + } + + /// ## Burning + + spec module { + /// Only TreasuryCompliance can have BurnCapability [[H3]][PERMISSION]. + /// If an account has BurnCapability, it is a TreasuryCompliance account. + invariant + forall a: address: + Diem::spec_has_burn_capability(a) ==> + Roles::spec_has_treasury_compliance_role_addr(a); + + /// Only the owner of BurnCapability can burn XUS [[H3]][PERMISSION]. + /// If the `total_value` or `preburn_value` for XUS is decreased, the + /// transaction should be signed by the owner of BurnCapability. + invariant update [suspendable] ( + old(Diem::spec_is_currency()) && + Diem::spec_is_currency() && + old(Diem::spec_currency_info().total_value) > Diem::spec_currency_info().total_value + ) ==> Diem::spec_signed_by_burn_capability_owner(); + invariant update [suspendable] ( + old(Diem::spec_is_currency()) && + Diem::spec_is_currency() && + old(Diem::spec_currency_info().preburn_value) > Diem::spec_currency_info().preburn_value + ) ==> Diem::spec_signed_by_burn_capability_owner(); + + /// The permission to burn XUS is unique [[I3]][PERMISSION]. + /// At most one address has a BurnCapability. + invariant + forall a1: address, a2: address: + (Diem::spec_has_burn_capability(a1) && Diem::spec_has_burn_capability(a2)) ==> a1 == a2; + + /// BurnCapability is not transferrable [[J3]][PERMISSION]. + /// BurnCapability is not copiable, and once it's published, it's not removed. + invariant update [suspendable] + forall a: address + where old(exists>(a)): + exists>(a); + } + + /// ## Preburning + + spec module { + /// Only DesignatedDealer can has the "preburn" permission [[H4]][PERMISSION]. + /// If an account has PreburnQueue or Preburn, it is a DesignatedDealer account. + invariant + forall a: address: + (Diem::spec_has_preburn_queue(a) || Diem::spec_has_preburn(a)) ==> + Roles::spec_has_designated_dealer_role_addr(a); + + /// Only the owner of PreburnQueue can preburn XUS [[H4]][PERMISSION]. + /// If the `preburn_value` for XUS is increased, the transaction should be + /// signed by the owner of PreburnQueue or Preburn. + invariant update [suspendable] ( + old(Diem::spec_is_currency()) && + Diem::spec_is_currency() && + old(Diem::spec_currency_info().preburn_value) < Diem::spec_currency_info().preburn_value + ) ==> (Diem::spec_signed_by_preburn_queue_owner() || Diem::spec_signed_by_preburn_owner()); + + /// PreburnQueue is not transferrable [[J4]][PERMISSION]. + /// PreburnQueue is not copiable, and once it's published, it's not removed. + invariant update [suspendable] + forall a: address + where old(exists>(a)): + exists>(a); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AccountFreezingTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AccountFreezingTests.move new file mode 100644 index 000000000..d7076726e --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AccountFreezingTests.move @@ -0,0 +1,122 @@ +#[test_only] +module DiemFramework::AccountFreezingTests { + use DiemFramework::AccountFreezing as AF; + use DiemFramework::Genesis; + use std::signer; + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun account_freezing_double_init(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + AF::initialize(&dr); + } + + #[test] + fun non_existent_account_not_frozen() { + assert!(!AF::account_is_frozen(@0x2), 0); + AF::assert_not_frozen(@0x2); + } + + #[test(a = @0x2)] + fun create_new(a: signer) { + let a_addr = signer::address_of(&a); + AF::create_for_test(&a); + AF::assert_not_frozen(a_addr); + } + + #[test(a = @0x2)] + #[expected_failure(abort_code = 518, location = AF)] + fun create_new_already_has_freezing_bit(a: signer) { + AF::create_for_test(&a); + AF::create_for_test(&a); + } + + #[test(a = @0x2)] + fun create_new_not_frozen(a: signer) { + let a_addr = signer::address_of(&a); + AF::create_for_test(&a); + AF::assert_not_frozen(a_addr); + } + + #[test(a = @0x2, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun freeze_account_not_tc(a: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + AF::create_for_test(&a); + AF::freeze_account(&a, @0x2); + } + + #[test(tc = @TreasuryCompliance, a = @0x2)] + #[expected_failure(abort_code = 257, location = DiemFramework::DiemTimestamp)] + fun freeze_account_not_operating(tc: signer, a: signer) { + AF::create_for_test(&a); + AF::freeze_account(&tc, @0x2); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 775, location = AF)] + fun cannot_freeze_diem_root(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + AF::freeze_account(&tc, @DiemRoot); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1031, location = AF)] + fun cannot_freeze_treasury_compliance(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + AF::freeze_account(&tc, @TreasuryCompliance); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 517, location = AF)] + fun freeze_no_freezing_bit(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + AF::freeze_account(&tc, @0x2); + } + + #[test(a = @0x2, tc = @TreasuryCompliance, dr = @DiemRoot)] + fun account_frozen_after_freeze(a: signer, tc: signer, dr: signer) { + let a_addr = signer::address_of(&a); + Genesis::setup(&dr, &tc); + AF::create_for_test(&a); + AF::assert_not_frozen(a_addr); + AF::freeze_account(&tc, @0x2); + assert!(AF::account_is_frozen(a_addr), 0); + } + + #[test(tc = @TreasuryCompliance, a = @0x2)] + #[expected_failure(abort_code = 257, location = DiemFramework::DiemTimestamp)] + fun unfreeze_account_not_operating(tc: signer, a: signer) { + AF::create_for_test(&a); + AF::unfreeze_account(&tc, @0x2); + } + + #[test(a = @0x2, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun unfreeze_account_not_tc(a: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + AF::create_for_test(&a); + AF::unfreeze_account(&a, @0x2); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 517, location = AF)] + fun unfreeze_no_freezing_bit(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + AF::unfreeze_account(&tc, @0x2); + } + + #[test(a = @0x2, tc = @TreasuryCompliance, dr = @DiemRoot)] + fun account_unfrozen_after_unfreeze(a: signer, tc: signer, dr: signer) { + let a_addr = signer::address_of(&a); + Genesis::setup(&dr, &tc); + + AF::create_for_test(&a); + AF::assert_not_frozen(a_addr); + AF::freeze_account(&tc, @0x2); + + assert!(AF::account_is_frozen(a_addr), 0); + AF::unfreeze_account(&tc, @0x2); + AF::assert_not_frozen(a_addr); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AccountLimits.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AccountLimits.move new file mode 100644 index 000000000..7201eeb88 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AccountLimits.move @@ -0,0 +1,183 @@ +#[test_only] +module DiemFramework::AccountLimitsTests { + use std::signer; + use DiemFramework::Genesis; + use DiemFramework::AccountLimits; + use DiemFramework::XUS::XUS; + use DiemFramework::Roles; + + struct Hold has key { x: T } + public fun hold(account: &signer, x: T) { + move_to(account, Hold{ x }) + } + + fun setup(dr: &signer, tc: &signer, vasp: &signer) { + Genesis::setup(dr, tc); + + Roles::new_parent_vasp_role(tc, vasp); + + AccountLimits::publish_unrestricted_limits_for_testing(vasp); + AccountLimits::publish_window(dr, vasp, signer::address_of(vasp)); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun grant_mutation_capability_after_genesis(dr: signer, tc: signer, vasp: signer) { + Genesis::setup(&dr, &tc); + + hold(&vasp, AccountLimits::grant_mutation_capability(&vasp)); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + fun publish_window(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 262, location = AccountLimits)] + fun publish_window_twice(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + + AccountLimits::publish_window(&dr, &vasp, signer::address_of(&vasp)); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun publish_window_non_diem_root(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::publish_window(&vasp, &vasp, signer::address_of(&vasp)); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 5, location = AccountLimits)] + fun publish_window_non_existent_limit_address(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::publish_window(&dr, &vasp, @0x42 /* non-exsistent */); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 6, location = AccountLimits)] + fun publish_unrestricted_limits_for_testing_twice(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::publish_unrestricted_limits_for_testing(&vasp); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + fun update_limits_definition_1(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::update_limits_definition( + &tc, + signer::address_of(&vasp), + 100, /* new_max_inflow */ + 200, /* new_max_outflow */ + 150, /* new_max_holding_balance */ + 10000, /* new_time_period */ + ) + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + fun update_limits_definition_2(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::update_limits_definition( + &tc, + signer::address_of(&vasp), + 0, /* new_max_inflow */ + 0, /* new_max_outflow */ + 150, /* new_max_holding_balance */ + 10000, /* new_time_period */ + ) + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + fun update_limits_definition_twice(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::update_limits_definition( + &tc, + signer::address_of(&vasp), + 100, /* new_max_inflow */ + 200, /* new_max_outflow */ + 150, /* new_max_holding_balance */ + 10000, /* new_time_period */ + ); + AccountLimits::update_limits_definition( + &tc, + signer::address_of(&vasp), + 0, /* new_max_inflow */ + 0, /* new_max_outflow */ + 150, /* new_max_holding_balance */ + 10000, /* new_time_period */ + ) + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun update_limits_definition_non_tc(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::update_limits_definition( + &dr, + signer::address_of(&vasp), + 100, /* new_max_inflow */ + 200, /* new_max_outflow */ + 150, /* new_max_holding_balance */ + 10000, /* new_time_period */ + ) + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 5, location = AccountLimits)] + fun update_limits_definition_non_exsistent(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + AccountLimits::update_limits_definition( + &tc, + @0x42, // non-exsistent + 100, /* new_max_inflow */ + 200, /* new_max_outflow */ + 150, /* new_max_holding_balance */ + 10000, /* new_time_period */ + ) + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + fun update_window_info(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + let vasp_addr = signer::address_of(&vasp); + AccountLimits::update_window_info( + &tc, + vasp_addr, + 120, + vasp_addr, + ); + AccountLimits::update_window_info( + &tc, + vasp_addr, + 0, + vasp_addr, + ); + AccountLimits::update_window_info( + &tc, + vasp_addr, + 120, + vasp_addr, + ); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun update_window_info_non_tc(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + let vasp_addr = signer::address_of(&vasp); + AccountLimits::update_window_info( + &dr, + vasp_addr, + 120, + vasp_addr, + ); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vasp = @0x2)] + fun has_limits_published(dr: signer, tc: signer, vasp: signer) { + setup(&dr, &tc, &vasp); + assert!(AccountLimits::has_limits_published(signer::address_of(&vasp)), 1); + assert!(!AccountLimits::has_limits_published(@0x42 /* non-exsistent */), 3); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AuthenticatorTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AuthenticatorTests.move new file mode 100644 index 000000000..c7633e385 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/AuthenticatorTests.move @@ -0,0 +1,118 @@ +#[test_only] +module DiemFramework::AuthenticatorTests { + use DiemFramework::Authenticator; + use std::vector; + + #[test] + fun create_valid_multisig_policies_and_compute_auth_keys() { + let pubkey1 = x"c48b687a1dd8265101b33df6ae0b6825234e3f28df9ecb38fb286cf76dae919d"; + let pubkey2 = x"4b2a60883383be0ba24ed79aa5a6c9379728099a7b0c57edcec193a14ea5fce2"; + let pubkey3 = x"323285d3d4b0f19482730c5f481d9f745c2927d73c231bad47859d9b2f7376f1"; + + let keys = vector::empty>(); + vector::push_back(&mut keys, pubkey1); + let t = Authenticator::create_multi_ed25519(copy keys, 1); + let auth_key = Authenticator::multi_ed25519_authentication_key(&t); + + vector::push_back(&mut keys, pubkey2); + t = Authenticator::create_multi_ed25519(copy keys, 1); + assert!(Authenticator::multi_ed25519_authentication_key(&t) != copy auth_key, 3006); + t = Authenticator::create_multi_ed25519(copy keys, 2); + assert!(Authenticator::multi_ed25519_authentication_key(&t) != copy auth_key, 3007); + + vector::push_back(&mut keys, copy pubkey3); + t = Authenticator::create_multi_ed25519(copy keys, 1); + assert!(Authenticator::multi_ed25519_authentication_key(&t) != copy auth_key, 3008); + t = Authenticator::create_multi_ed25519(copy keys, 2); + assert!(Authenticator::multi_ed25519_authentication_key(&t) != copy auth_key, 3009); + // check that auth key matches expect result + assert!( + Authenticator::multi_ed25519_authentication_key(&t) + == + x"1761bca45f83ecdefe202650ca5ba9518b9c2cc032667a95b275dc3f43173ae0", + 3011 + ); + + // duplicate keys are ok + vector::push_back(&mut keys, pubkey3); + t = Authenticator::create_multi_ed25519(copy keys, 3); + assert!(Authenticator::multi_ed25519_authentication_key(&t) != copy auth_key, 3012); + + assert!(Authenticator::threshold(&t) == 3, 3013); + assert!(Authenticator::public_keys(&t) == &keys, 3014); + } + + #[test] + #[expected_failure(abort_code = 7, location = Authenticator)] + fun empty_policy_should_be_rejected() { + let keys = vector::empty>(); + Authenticator::create_multi_ed25519(keys, 0); + } + + #[test] + #[expected_failure(abort_code = 263, location = Authenticator)] + fun bad_threshold_should_be_rejected_threshold_1_for_empty_keys() { + let keys = vector::empty>(); + Authenticator::create_multi_ed25519(keys, 1); + } + + #[test] + #[expected_failure(abort_code = 519, location = Authenticator)] + fun bad_threshold_should_be_rejected_threshold_3_for_34_keys() { + let pubkey = x""; + + let keys = vector::empty>(); + let index = 0; + while (index < 34) { + vector::push_back(&mut keys, copy pubkey); + index = index + 1; + }; + let _auth_key = + Authenticator::create_multi_ed25519(keys, 3); + } + + #[test] + #[expected_failure(abort_code = 263, location = Authenticator)] + fun bad_threshold_should_be_rejected_threshold_2_for_1_key() { + let keys = vector::empty>(); + vector::push_back( + &mut keys, + x"2000000000000000000000000000000000000000000000000000000000000000" + ); + Authenticator::create_multi_ed25519(keys, 2); + } + + #[test] + #[expected_failure(abort_code = 7, location = Authenticator)] + fun bad_threshold_should_be_rejected_threshold_0_for_1_address() { + let keys = vector::empty>(); + vector::push_back( + &mut keys, + x"2000000000000000000000000000000000000000000000000000000000000000" + ); + Authenticator::create_multi_ed25519(keys, 0); + } + + #[test] + fun one_of_one_multi_ed25519_should_have_different_auth_key_than_ed25519_with_same_public_key() { + let pubkey = x"c48b687a1dd8265101b33df6ae0b6825234e3f28df9ecb38fb286cf76dae919d"; + let keys = vector::empty>(); + vector::push_back( + &mut keys, + copy pubkey + ); + + let t = Authenticator::create_multi_ed25519(keys, 1); + assert!( + Authenticator::multi_ed25519_authentication_key(&t) != + Authenticator::ed25519_authentication_key(copy pubkey), + 3011 + ); + assert!( + x"ba10abb6d85ea3897baa1cae457fc724a916d258bd47ab852f200c5851a6d057" + == + Authenticator::ed25519_authentication_key(pubkey), + 3012 + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CRSNTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CRSNTests.move new file mode 100644 index 000000000..62a37f7a8 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CRSNTests.move @@ -0,0 +1,242 @@ +#[test_only] +module DiemFramework::CRSNTests { + use DiemFramework::CRSN; + use DiemFramework::Genesis; + use std::signer; + use std::bit_vector; + + #[test_only] + public fun setup(dr: &signer, tc: &signer, _: &signer) { + Genesis::setup(dr, tc); + CRSN::allow_crsns(dr) + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1281, location = CRSN)] + public fun cant_publish_until_init(a: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + CRSN::test_publish(&a, 0, 10); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1537, location = CRSN)] + public fun double_init(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::allow_crsns(&dr); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun publish_exists_after_small_size(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + + CRSN::test_publish(&a, 0, 10); + assert!(CRSN::has_crsn(addr), 0); + assert!(CRSN::min_nonce(addr) == 0, 1); + assert!(bit_vector::length(&CRSN::slots(addr)) == 10, 2); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun publish_exists_after_medium_size(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + + CRSN::test_publish(&a, 20, 128); + assert!(CRSN::has_crsn(addr), 0); + assert!(CRSN::min_nonce(addr) == 20, 1); + assert!(bit_vector::length(&CRSN::slots(addr)) == 128, 2); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun publish_exists_after_large_size(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + + CRSN::test_publish(&a, 505, CRSN::max_crsn_size()); + assert!(CRSN::has_crsn(addr), 0); + assert!(CRSN::min_nonce(addr) == 505, 1); + assert!(bit_vector::length(&CRSN::slots(addr)) == CRSN::max_crsn_size(), 2); + } + + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 257, location = CRSN)] + public fun double_publish(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 0, 10); + CRSN::test_publish(&a, 0, 10); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 519, location = CRSN)] + public fun publish_zero_size(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 10, 0); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun publish_at_max_size(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 10, CRSN::max_crsn_size()); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 775, location = CRSN)] + public fun publish_above_max_size(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 10, CRSN::max_crsn_size() + 1); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun test_has_crsn(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + assert!(!CRSN::has_crsn(addr), 0); + CRSN::test_publish(&a, 0, 10); + assert!(CRSN::has_crsn(addr), 1); + } + + #[test(a=@0xCAFE)] + #[expected_failure(abort_code = 1, location = CRSN)] + public fun record_no_crsn(a: signer) { + CRSN::test_record(&a, 0); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun record_too_high_low_accept(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 100, 10); + assert!(!CRSN::test_record(&a, 110), 0); + assert!(!CRSN::test_record(&a, 111), 1); + // We allow recording in the past + assert!(CRSN::test_record(&a, 99), 2); + // But the check will fail since that happens in the prologue + assert!(!CRSN::test_check(&a, 99), 2); + assert!(CRSN::test_record(&a, 100), 3); + assert!(CRSN::test_record(&a, 109), 4); + assert!(!CRSN::test_record(&a, 109), 5); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun prevent_replay(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 100, 10); + assert!(CRSN::test_record(&a, 101), 0); + assert!(!CRSN::test_record(&a, 101), 1); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun prevent_replay_with_shift(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 100, 10); + assert!(CRSN::test_record(&a, 100), 0); + assert!(!CRSN::test_check(&a, 100), 1); + assert!(CRSN::test_record(&a, 100), 1); + assert!(CRSN::min_nonce(signer::address_of(&a)) == 101, 2); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun multiple_shifts_of_window(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + CRSN::test_publish(&a, 100, 10); + assert!(CRSN::test_record(&a, 101), 0); + assert!(CRSN::test_record(&a, 102), 0); + assert!(CRSN::test_record(&a, 103), 0); + + assert!(CRSN::test_record(&a, 106), 0); + assert!(CRSN::test_record(&a, 107), 0); + assert!(CRSN::test_record(&a, 108), 0); + + // The window should not have shifted + assert!(CRSN::min_nonce(addr) == 100, 1); + assert!(CRSN::test_record(&a, 100), 0); + // The window should now shift until it gets stuck on 104 + assert!(CRSN::min_nonce(addr) == 104, 1); + assert!(CRSN::test_record(&a, 104), 0); + assert!(CRSN::min_nonce(addr) == 105, 1); + assert!(CRSN::test_record(&a, 105), 0); + assert!(CRSN::min_nonce(addr) == 109, 1); + + // Now make sure that the window has shifted and opened-up higher slots + assert!(CRSN::test_record(&a, 110), 0); + assert!(CRSN::test_record(&a, 111), 0); + assert!(CRSN::test_record(&a, 112), 0); + assert!(CRSN::test_record(&a, 113), 0); + assert!(CRSN::test_record(&a, 114), 0); + assert!(CRSN::test_record(&a, 115), 0); + assert!(CRSN::min_nonce(addr) == 109, 1); + assert!(CRSN::test_record(&a, 109), 0); + assert!(CRSN::min_nonce(addr) == 116, 1); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1031, location = CRSN)] + public fun force_expire_zero(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + CRSN::test_publish(&a, 100, 10); + CRSN::test_force_expire(&a, 0); + } + + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun force_expire_single(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + CRSN::test_publish(&a, 100, 10); + CRSN::test_force_expire(&a, 1); + assert!(CRSN::min_nonce(addr) == 101, 1); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun force_expire_shift_over_set_bits(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + CRSN::test_publish(&a, 0, 100); + assert!(CRSN::test_record(&a, 1), 0); + assert!(CRSN::test_record(&a, 2), 0); + assert!(CRSN::test_record(&a, 3), 0); + CRSN::test_force_expire(&a, 1); + assert!(CRSN::min_nonce(addr) == 4, 1); + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun force_expire_past_set_bits(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + CRSN::test_publish(&a, 0, 100); + assert!(CRSN::test_record(&a, 1), 0); + assert!(CRSN::test_record(&a, 2), 0); + assert!(CRSN::test_record(&a, 3), 0); + CRSN::test_force_expire(&a, 15); + assert!(CRSN::min_nonce(addr) == 15, 1); + let i = 0; + let len = 100; + let slots = CRSN::slots(addr); + + while (i < len) { + assert!(!bit_vector::is_index_set(&slots, i), 2); + i = i + 1; + } + } + + #[test(a=@0xCAFE, tc = @TreasuryCompliance, dr = @DiemRoot)] + public fun force_expire_past_window_size(a: signer, tc: signer, dr: signer) { + setup(&dr, &tc, &a); + let addr = signer::address_of(&a); + CRSN::test_publish(&a, 0, 100); + assert!(CRSN::test_record(&a, 1), 0); + assert!(CRSN::test_record(&a, 2), 0); + assert!(CRSN::test_record(&a, 3), 0); + CRSN::test_force_expire(&a, 10000); + assert!(CRSN::min_nonce(addr) == 10000, 1); + let i = 0; + let len = 100; + let slots = CRSN::slots(addr); + + while (i < len) { + assert!(!bit_vector::is_index_set(&slots, i), 2); + i = i + 1; + } + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CoreAddressesTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CoreAddressesTests.move new file mode 100644 index 000000000..2d0d02468 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CoreAddressesTests.move @@ -0,0 +1,24 @@ +#[test_only] +module DiemFramework::CoreAddressesTests { + use DiemFramework::CoreAddresses; + + #[test(dr = @DiemRoot)] + fun test_assert_diem_root(dr: signer) { + CoreAddresses::assert_diem_root(&dr); + } + + #[test(tc = @TreasuryCompliance)] + fun test_assert_treasury_compliance(tc: signer) { + CoreAddresses::assert_treasury_compliance(&tc); + } + + #[test(vm = @VMReserved)] + fun test_assert_vm(vm: signer) { + CoreAddresses::assert_vm(&vm); + } + + #[test(ci = @CurrencyInfo)] + fun test_assert_currency_info(ci: signer) { + CoreAddresses::assert_currency_info(&ci); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CurrenciesTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CurrenciesTests.move new file mode 100644 index 000000000..dc820648b --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/CurrenciesTests.move @@ -0,0 +1,31 @@ +#[test_only] +module DiemFramework::CurrenciesTests { + use DiemFramework::DualAttestation; + use DiemFramework::DiemAccount; + use DiemFramework::XUS::XUS; + use DiemFramework::XDX::XDX; + use DiemFramework::Genesis; + + // Check that the add_all_currencies flag does the expected thing + #[test(account = @TreasuryCompliance, dr = @DiemRoot)] + fun currencies(account: signer, dr: signer) { + Genesis::setup(&dr, &account); + let account = &account; + let dummy_auth_key_prefix = x"00000000000000000000000000000001"; + DiemAccount::create_designated_dealer( + account, @0x2, copy dummy_auth_key_prefix, b"name", false + ); + DiemAccount::create_designated_dealer( + account, @0x3, dummy_auth_key_prefix, b"other_name", true + ); + + assert!(DiemAccount::accepts_currency(@0x2), 0); + assert!(!DiemAccount::accepts_currency(@0x2), 2); + assert!(DualAttestation::human_name(@0x2) == b"name", 77); + assert!(DualAttestation::base_url(@0x2) == b"", 78); + assert!(DualAttestation::compliance_public_key(@0x2) == b"", 79); + + assert!(DiemAccount::accepts_currency(@0x3), 3); + assert!(DiemAccount::accepts_currency(@0x3), 5); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemBlockTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemBlockTests.move new file mode 100644 index 000000000..2f5e1bf91 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemBlockTests.move @@ -0,0 +1,13 @@ +#[test_only] +module DiemFramework::DiemBlockTests { + use DiemFramework::Genesis; + use DiemFramework::DiemBlock; + + // TODO: the error code doesn't seem correct, juding by the name of the test. + #[test(tc = @TreasuryCompliance, dr = @DiemRoot, account = @0x100)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun invalid_initialization_address(account: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemBlock::initialize_block_metadata(&account); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemConfigTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemConfigTests.move new file mode 100644 index 000000000..b64839093 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemConfigTests.move @@ -0,0 +1,39 @@ +#[test_only] +module DiemFramework::OnChainConfigTests { + use DiemFramework::DiemConfig; + use DiemFramework::Genesis; + + #[test(account = @0x1)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun init_before_genesis(account: signer) { + DiemConfig::initialize(&account); + } + + #[test(account = @0x2, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun invalid_address_init(account: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemConfig::initialize(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 261, location = DiemConfig)] + fun invalid_get(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemConfig::get(); + } + + #[test(account = @0x1, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 516, location = DiemConfig)] + fun invalid_set(account: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemConfig::set_for_testing(&account, 0); + } + + #[test(account = @0x1, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun invalid_publish(account: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemConfig::publish_new_config_for_testing(&account, 0); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemTests.move new file mode 100644 index 000000000..59b3f3719 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemTests.move @@ -0,0 +1,48 @@ +#[test_only] +module DiemFramework::DiemTests { + use DiemFramework::XUS::XUS; + use DiemFramework::Genesis; + use DiemFramework::Diem; + use std::signer; + + struct R has key { x: T } + struct FakeCoin has store { value: u64 } + + fun fetch(account: &signer): T acquires R { + let R { x } = move_from>(signer::address_of(account)); + x + } + + fun store(account: &signer, x: T) { + move_to(account, R { x }); + } + + fun transmute(account: &signer, x: T1): T2 acquires R { + // There was once a bug that R and R shared the same storage key for U != T, + // making it possible to perform a transmuatation. + store(account, x); + fetch(account) + } + + fun become_rich(account: &signer) acquires R { + let fake = FakeCoin { value: 400000 }; + let real = transmute(account, fake); + Diem::destroy_zero(real); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot, account = @0x100)] + #[expected_failure] + fun cannot_print_counterfeit_money(tc: signer, dr: signer, account: signer) acquires R { + Genesis::setup(&dr, &tc); + + become_rich(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun cannot_initialize_after_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + + Diem::initialize(&dr); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemTimestampTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemTimestampTests.move new file mode 100644 index 000000000..189e8f35f --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemTimestampTests.move @@ -0,0 +1,137 @@ +#[test_only] +module DiemFramework::DiemTimestampTests { + use DiemFramework::Genesis; + use DiemFramework::DiemTimestamp; + use std::vector; + use std::unit_test; + + fun get_signer(): signer { + vector::pop_back(&mut unit_test::create_signers_for_testing(1)) + } + + #[test] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun set_time_has_started_non_dr_pre_genesis() { + let s = get_signer(); + DiemTimestamp::set_time_has_started_for_testing(&s); + } + + #[test(dr = @DiemRoot)] + fun set_time_has_started_dr_pre_genesis(dr: signer) { + DiemTimestamp::set_time_has_started_for_testing(&dr); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + #[expected_failure(abort_code = 1, location = DiemTimestamp)] + fun set_time_has_started_dr_post_genesis(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + DiemTimestamp::set_time_has_started_for_testing(&dr); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + #[expected_failure(abort_code = 1, location = DiemTimestamp)] + fun set_time_has_started_non_dr_post_genesis(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + let s = get_signer(); + DiemTimestamp::set_time_has_started_for_testing(&s); + } + + #[test] + #[expected_failure(abort_code = 257, location = DiemTimestamp)] + fun update_global_time_pre_genesis() { + let s = get_signer(); + DiemTimestamp::update_global_time(&s, @0x0, 0); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + #[expected_failure(abort_code = 514, location = DiemFramework::CoreAddresses)] + fun update_global_time_post_genesis_non_vm(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + DiemTimestamp::update_global_time(&dr, @0x1, 0); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vm = @VMReserved)] + fun update_global_time_post_genesis_vm_nil_proposer_equal_timestamp(dr: signer, tc: signer, vm: signer) { + Genesis::setup(&dr, &tc); + assert!(DiemTimestamp::now_microseconds() == 0, 0); + DiemTimestamp::update_global_time(&vm, @VMReserved, 0); + assert!(DiemTimestamp::now_microseconds() == 0, 1); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vm = @VMReserved)] + #[expected_failure(abort_code = 519, location = DiemTimestamp)] + fun update_global_time_post_genesis_vm_nil_proposer_increasing_timestamp(dr: signer, tc: signer, vm: signer) { + Genesis::setup(&dr, &tc); + assert!(DiemTimestamp::now_microseconds() == 0, 0); + DiemTimestamp::update_global_time(&vm, @VMReserved, 1); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vm = @VMReserved)] + #[expected_failure(abort_code = 519, location = DiemTimestamp)] + fun update_global_time_post_genesis_vm_not_nil_proposer_equal_timestamp(dr: signer, tc: signer, vm: signer) { + Genesis::setup(&dr, &tc); + assert!(DiemTimestamp::now_microseconds() == 0, 0); + DiemTimestamp::update_global_time(&vm, @0x1, 0); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, vm = @VMReserved)] + fun update_global_time_post_genesis_vm_not_nil_proposer_increasing_timestamp(dr: signer, tc: signer, vm: signer) { + Genesis::setup(&dr, &tc); + assert!(DiemTimestamp::now_microseconds() == 0, 0); + DiemTimestamp::update_global_time(&vm, @0x1, 1); + assert!(DiemTimestamp::now_microseconds() == 1, 1); + } + + #[test] + #[expected_failure(abort_code = 257, location = DiemTimestamp)] + fun now_microseconds_pre_genesis() { + DiemTimestamp::now_microseconds(); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + fun now_microseconds_post_genesis(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + assert!(DiemTimestamp::now_microseconds() == 0, 0); + } + + #[test] + #[expected_failure(abort_code = 257, location = DiemTimestamp)] + fun now_seconds_pre_genesis() { + DiemTimestamp::now_seconds(); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + fun now_seconds_post_genesis(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + assert!(DiemTimestamp::now_seconds() == 0, 0); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + fun is_genesis(dr: signer, tc: signer) { + assert!(DiemTimestamp::is_genesis(), 0); + DiemTimestamp::assert_genesis(); + Genesis::setup(&dr, &tc); + assert!(!DiemTimestamp::is_genesis(), 1); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + #[expected_failure(abort_code = 1, location = DiemTimestamp)] + fun assert_genesis(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + DiemTimestamp::assert_genesis(); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + fun is_operating(dr: signer, tc: signer) { + assert!(!DiemTimestamp::is_operating(), 0); + Genesis::setup(&dr, &tc); + DiemTimestamp::assert_operating(); + assert!(DiemTimestamp::is_operating(), 1); + } + + #[test] + #[expected_failure(abort_code = 257, location = DiemTimestamp)] + fun assert_operating() { + DiemTimestamp::assert_operating(); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemVersionTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemVersionTests.move new file mode 100644 index 000000000..41bdfa048 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/DiemVersionTests.move @@ -0,0 +1,44 @@ +#[test_only] +module DiemFramework::DiemVersionTests { + use DiemFramework::DiemVersion; + use DiemFramework::Genesis; + + #[test(account = @0x1)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun init_before_genesis(account: signer) { + DiemVersion::initialize(&account, 0); + } + + #[test(account = @0x1)] + #[expected_failure(abort_code = 257, location = DiemFramework::DiemTimestamp)] + fun set_before_genesis(account: signer) { + DiemVersion::set(&account, 0); + } + + #[test(account = @0x2, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun invalid_address_init(account: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemVersion::initialize(&account, 0); + } + + #[test(account = @0x2, tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun invalid_setting_address(account: signer, tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemVersion::set(&account, 0); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 7, location = DiemVersion)] + fun non_increasing_version(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemVersion::set(&dr, 0); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun increasing_version(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + DiemVersion::set(&dr, 1); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/RegisteredCurrencyTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/RegisteredCurrencyTests.move new file mode 100644 index 000000000..35ad26c30 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/RegisteredCurrencyTests.move @@ -0,0 +1,26 @@ +#[test_only] +module DiemFramework::RegisteredCurrencyTests { + use DiemFramework::RegisteredCurrencies; + use DiemFramework::Genesis; + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, alice = @0x2)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun cannot_call_initialize_as_non_diem_root(dr: signer, tc: signer, alice: signer) { + Genesis::setup(&dr, &tc); + RegisteredCurrencies::initialize(&alice); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun cannot_call_initialize_outside_genesis(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + RegisteredCurrencies::initialize(&dr); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance)] + #[expected_failure(abort_code = 7, location = RegisteredCurrencies)] + fun cannot_add_currency_whose_currency_code_has_already_been_taken(dr: signer, tc: signer) { + Genesis::setup(&dr, &tc); + RegisteredCurrencies::add_currency_code(&dr, b"XDX"); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/RolesTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/RolesTests.move new file mode 100644 index 000000000..41c020468 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/RolesTests.move @@ -0,0 +1,383 @@ +#[test_only] +module DiemFramework::RolesTests{ + use DiemFramework::Roles; + use DiemFramework::Genesis; + use std::unit_test; + use std::vector; + use std::signer; + + fun get_account(): signer { + vector::pop_back(&mut unit_test::create_signers_for_testing(1)) + } + + #[test] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun grant_diem_root_wrong_addr_pre_genesis() { + let account = get_account(); + Roles::grant_diem_root_role(&account); + } + + #[test(tc = @TreasuryCompliance)] + #[expected_failure(abort_code = 5, location = Roles)] + fun tc_dne_pre_genesis(tc: signer) { + Roles::assert_treasury_compliance(&tc); + } + + #[test(dr = @DiemRoot)] + #[expected_failure(abort_code = 5, location = Roles)] + fun dr_dne_pre_genesis(dr: signer) { + Roles::assert_diem_root(&dr); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun genesis_root_roles_exist(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::assert_diem_root(&dr); + assert!(Roles::has_diem_root_role(&dr), 0); + + Roles::assert_treasury_compliance(&tc); + assert!(Roles::has_treasury_compliance_role(&tc), 0); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun tc_is_not_dr(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::assert_diem_root(&tc); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun dr_is_not_tc(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::assert_treasury_compliance(&dr); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun grant_diem_root_wrong_addr_post_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::grant_diem_root_role(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun grant_diem_root_correct_addr_post_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::grant_diem_root_role(&dr); + } + + #[test] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun grant_treasury_compliance_wrong_addr_pre_genesis() { + let account = get_account(); + Roles::grant_treasury_compliance_role(&account, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun grant_treasury_compliance_wrong_addr_post_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::grant_treasury_compliance_role(&dr, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun grant_treasury_compliance_wrong_granting_addr_post_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::grant_treasury_compliance_role(&tc, &tc); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun grant_treasury_compliance_correct_addrs(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::grant_treasury_compliance_role(&dr, &tc); + } + + #[test] + #[expected_failure(abort_code = 5, location = Roles)] + fun designated_dealer_role_dne() { + let account = get_account(); + Roles::assert_designated_dealer(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1539, location = Roles)] + fun designated_dealer_assert_wrong_role(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::assert_designated_dealer(&tc); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun grant_dd_role_non_tc_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_designated_dealer_role(&account, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun grant_dd_role_tc_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + assert!(!Roles::has_designated_dealer_role(&account), 0); + Roles::new_designated_dealer_role(&tc, &account); + assert!(Roles::has_designated_dealer_role(&account), 1); + Roles::assert_designated_dealer(&account); + Roles::assert_parent_vasp_or_designated_dealer(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 6, location = Roles)] + fun double_grant_dd_role_tc_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_designated_dealer_role(&tc, &account); + Roles::new_designated_dealer_role(&tc, &account); + } + + #[test] + #[expected_failure(abort_code = 5, location = Roles)] + fun validator_role_dne() { + let account = get_account(); + Roles::assert_validator(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1795, location = Roles)] + fun validator_assert_wrong_role(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::assert_validator(&tc); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun grant_validator_role_non_dr_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_validator_role(&account, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun grant_validator_role_dr_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + assert!(!Roles::has_validator_role(&account), 0); + Roles::new_validator_role(&dr, &account); + assert!(Roles::has_validator_role(&account), 1); + Roles::assert_validator(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 6, location = Roles)] + fun double_grant_validator_role_dr_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_validator_role(&dr, &account); + Roles::new_validator_role(&dr, &account); + } + + #[test] + #[expected_failure(abort_code = 5, location = Roles)] + fun validator_operator_role_dne() { + let account = get_account(); + Roles::assert_validator_operator(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2051, location = Roles)] + fun validator_operator_assert_wrong_role(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::assert_validator_operator(&tc); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun grant_validator_operator_role_non_dr_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_validator_operator_role(&account, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun grant_validator_operator_role_dr_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + assert!(!Roles::has_validator_operator_role(&account), 0); + Roles::new_validator_operator_role(&dr, &account); + assert!(Roles::has_validator_operator_role(&account), 1); + Roles::assert_validator_operator(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 6, location = Roles)] + fun double_grant_validator_operator_role_dr_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_validator_operator_role(&dr, &account); + Roles::new_validator_operator_role(&dr, &account); + } + + #[test] + #[expected_failure(abort_code = 5, location = Roles)] + fun parent_vasp_role_dne() { + let account = get_account(); + Roles::assert_parent_vasp_role(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun grant_parent_vasp_role_non_tc_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_parent_vasp_role(&account, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun grant_parent_vasp_role_tc_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + assert!(!Roles::has_parent_VASP_role(&account), 0); + Roles::new_parent_vasp_role(&tc, &account); + assert!(Roles::has_parent_VASP_role(&account), 1); + Roles::assert_parent_vasp_role(&account); + Roles::assert_parent_vasp_or_designated_dealer(&account); + Roles::assert_parent_vasp_or_child_vasp(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 6, location = Roles)] + fun double_grant_parent_vasp_role_tc_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_parent_vasp_role(&tc, &account); + Roles::new_parent_vasp_role(&tc, &account); + } + + #[test] + #[expected_failure(abort_code = 5, location = Roles)] + fun child_vasp_role_dne() { + let account = get_account(); + Roles::assert_child_vasp_role(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2307, location = Roles)] + fun child_vasp_assert_wrong_role(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_designated_dealer_role(&tc, &account); + Roles::assert_child_vasp_role(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 771, location = Roles)] + fun grant_child_vasp_role_non_parent_vasp_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let account = get_account(); + Roles::new_child_vasp_role(&tc, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun grant_child_vasp_role_parent_vasp_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let (account, pvasp) = { + let accounts = unit_test::create_signers_for_testing(2); + (vector::pop_back(&mut accounts), vector::pop_back(&mut accounts)) + }; + assert!(!Roles::has_child_VASP_role(&account), 0); + Roles::new_parent_vasp_role(&tc, &pvasp); + Roles::new_child_vasp_role(&pvasp, &account); + assert!(Roles::has_child_VASP_role(&account), 1); + Roles::assert_child_vasp_role(&account); + Roles::assert_parent_vasp_or_child_vasp(&account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 6, location = Roles)] + fun double_grant_child_vasp_role_tc_granter(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let (account, pvasp) = { + let accounts = unit_test::create_signers_for_testing(2); + (vector::pop_back(&mut accounts), vector::pop_back(&mut accounts)) + }; + Roles::new_parent_vasp_role(&tc, &pvasp); + Roles::new_child_vasp_role(&pvasp, &account); + Roles::new_child_vasp_role(&pvasp, &account); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun who_can_hold_balance(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let (dd_account, child_account, pvasp) = { + let accounts = unit_test::create_signers_for_testing(3); + ( + vector::pop_back(&mut accounts), + vector::pop_back(&mut accounts), + vector::pop_back(&mut accounts) + ) + }; + + Roles::new_parent_vasp_role(&tc, &pvasp); + Roles::new_child_vasp_role(&pvasp, &child_account); + Roles::new_designated_dealer_role(&tc, &dd_account); + + assert!(Roles::can_hold_balance(&dd_account), 0); + assert!(Roles::can_hold_balance(&child_account), 1); + assert!(Roles::can_hold_balance(&pvasp), 2); + } + + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun role_ids(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let (validator_account, validator_operator_account, dd_account, child_account, pvasp) = { + let accounts = unit_test::create_signers_for_testing(5); + ( + vector::pop_back(&mut accounts), + vector::pop_back(&mut accounts), + vector::pop_back(&mut accounts), + vector::pop_back(&mut accounts), + vector::pop_back(&mut accounts), + ) + }; + + Roles::new_parent_vasp_role(&tc, &pvasp); + Roles::new_child_vasp_role(&pvasp, &child_account); + Roles::new_designated_dealer_role(&tc, &dd_account); + Roles::new_validator_role(&dr, &validator_account); + Roles::new_validator_operator_role(&dr, &validator_operator_account); + + assert!(Roles::get_role_id(signer::address_of(&dr)) == 0, 0); + assert!(Roles::get_role_id(signer::address_of(&tc)) == 1, 1); + assert!(Roles::get_role_id(signer::address_of(&dd_account)) == 2, 2); + assert!(Roles::get_role_id(signer::address_of(&validator_account)) == 3, 3); + assert!(Roles::get_role_id(signer::address_of(&validator_operator_account)) == 4, 4); + assert!(Roles::get_role_id(signer::address_of(&pvasp)) == 5, 5); + assert!(Roles::get_role_id(signer::address_of(&child_account)) == 6, 6); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 5, location = Roles)] + fun get_role_id_no_role(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + Roles::get_role_id(@0x1); + } + + #[test] + #[expected_failure(abort_code = 5, location = Roles)] + fun assert_parent_or_designated_dealer_role_dne() { + let account = get_account(); + Roles::assert_parent_vasp_or_designated_dealer(&account); + } + + #[test] + #[expected_failure(abort_code = 5, location = Roles)] + fun assert_parent_or_child_role_dne() { + let account = get_account(); + Roles::assert_parent_vasp_or_child_vasp(&account); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/SharedEd25519PublicKeyTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/SharedEd25519PublicKeyTests.move new file mode 100644 index 000000000..310aa1dd8 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/SharedEd25519PublicKeyTests.move @@ -0,0 +1,110 @@ +#[test_only] +module DiemFramework::SharedEd25519PublicKeyTests { + use DiemFramework::DiemAccount; + use DiemFramework::Genesis; + use DiemFramework::SharedEd25519PublicKey; + use DiemFramework::XUS::XUS; + + use std::signer; + + fun setup(dr: &signer, tc: &signer, account: &signer) { + let addr = signer::address_of(account); + + Genesis::setup(dr, tc); + DiemAccount::create_parent_vasp_account(tc, addr, x"0d3e1bd412376e933a0e794d65b41f97", b"", false); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0x100)] + fun publish_and_rotate_shared_key(dr: signer, tc: signer, account: signer) { + let dr = &dr; + let tc = &tc; + let account = &account; + + let addr = signer::address_of(account); + + setup(dr, tc, account); + + let old_auth_key = DiemAccount::authentication_key(addr); + // from RFC 8032 + let pubkey1 = x"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + SharedEd25519PublicKey::publish(account, copy pubkey1); + let new_auth_key = DiemAccount::authentication_key(addr); + + // check that publishing worked + assert!(SharedEd25519PublicKey::exists_at(addr), 3000); + assert!(SharedEd25519PublicKey::key(addr) == pubkey1, 3001); + + // publishing should extract the sender's key rotation capability + assert!(DiemAccount::delegated_key_rotation_capability(addr), 3002); + // make sure the sender's auth key has changed + assert!(copy new_auth_key != old_auth_key, 3003); + + // now rotate to another pubkey and redo the key-related checks + // from RFC 8032 + let pubkey2 = x"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; + SharedEd25519PublicKey::rotate_key(account, copy pubkey2); + assert!(SharedEd25519PublicKey::key(addr) == pubkey2, 3004); + // make sure the auth key changed again + assert!(new_auth_key != DiemAccount::authentication_key(addr), 3005); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0x100)] + #[expected_failure(abort_code = 261, location = SharedEd25519PublicKey)] + fun get_key_for_non_shared_account_should_fail(dr: signer, tc: signer, account: signer) { + setup(&dr, &tc, &account); + + SharedEd25519PublicKey::key(signer::address_of(&account)); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0x100)] + #[expected_failure(abort_code = 7, location = SharedEd25519PublicKey)] + fun publish_key_with_bad_length_1(dr: signer, tc: signer, account: signer) { + setup(&dr, &tc, &account); + + let invalid_pubkey = x"0000"; + SharedEd25519PublicKey::publish(&account, invalid_pubkey); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0x100)] + #[expected_failure(abort_code = 7, location = SharedEd25519PublicKey)] + fun publish_key_with_bad_length_2(dr: signer, tc: signer, account: signer) { + setup(&dr, &tc, &account); + + let invalid_pubkey = x"10003d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + SharedEd25519PublicKey::publish(&account, invalid_pubkey); + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0x100)] + #[expected_failure(abort_code = 7, location = SharedEd25519PublicKey)] + fun rotate_to_key_with_bad_length(dr: signer, tc: signer, account: signer) { + setup(&dr, &tc, &account); + + // from RFC 8032 + let valid_pubkey = x"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + SharedEd25519PublicKey::publish(&account, valid_pubkey); + // now rotate to an invalid key + let invalid_pubkey = x"010000"; + SharedEd25519PublicKey::rotate_key(&account, invalid_pubkey) + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0x100)] + #[expected_failure(abort_code = 7, location = SharedEd25519PublicKey)] + fun rotate_to_key_with_good_length_but_bad_contents(dr: signer, tc: signer, account: signer) { + setup(&dr, &tc, &account); + + let valid_pubkey = x"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + SharedEd25519PublicKey::publish(&account, valid_pubkey); + // now rotate to an invalid key + let invalid_pubkey = x"0000000000000000000000000000000000000000000000000000000000000000"; + SharedEd25519PublicKey::rotate_key(&account, invalid_pubkey) + } + + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0x100)] + #[expected_failure(abort_code = 261, location = SharedEd25519PublicKey)] + fun rotate_key_on_non_shared_account(dr: signer, tc: signer, account: signer) { + setup(&dr, &tc, &account); + + let invalid_pubkey = x""; + SharedEd25519PublicKey::rotate_key(&account, invalid_pubkey); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/SignatureTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/SignatureTests.move new file mode 100644 index 000000000..d7650a298 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/SignatureTests.move @@ -0,0 +1,43 @@ +#[test_only] +module DiemFramework::SignatureTests{ + use DiemFramework::Signature; + + // Test fot public key validation + #[test] + fun signature() { + // from RFC 8032 + let valid_pubkey = x"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + let short_pubkey = x"0100"; + // concatenation of the two above + let long_pubkey = x"01003d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + let invalid_pubkey = x"0000000000000000000000000000000000000000000000000000000000000000"; + + let short_signature = x"0100"; + let long_signature = x"0062d6be393b8ec77fb2c12ff44ca8b5bd8bba83b805171bc99f0af3bdc619b20b8bd529452fe62dac022c80752af2af02fb610c20f01fb67a4d72789db2b8b703"; + let valid_signature = x"62d6be393b8ec77fb2c12ff44ca8b5bd8bba83b805171bc99f0af3bdc619b20b8bd529452fe62dac022c80752af2af02fb610c20f01fb67a4d72789db2b8b703"; + + let message = x"0000000000000000000000000000000000000000000000000000000000000000"; + let pubkey = x"7013b6ed7dde3cfb1251db1b04ae9cd7853470284085693590a75def645a926d"; + + assert!(Signature::ed25519_validate_pubkey(copy valid_pubkey), 9003); + assert!(!Signature::ed25519_validate_pubkey(copy short_pubkey), 9004); + assert!(!Signature::ed25519_validate_pubkey(copy long_pubkey), 9005); + assert!(!Signature::ed25519_validate_pubkey(copy invalid_pubkey), 9006); + + + // now check that Signature::ed25519_verify works with well- and ill-formed data and never aborts + // valid signature, invalid pubkey (too short, too long, bad small subgroup) + assert!(!Signature::ed25519_verify(copy valid_signature, copy short_pubkey, x""), 9004); + assert!(!Signature::ed25519_verify(copy valid_signature, copy long_pubkey, x""), 9005); + assert!(!Signature::ed25519_verify(copy valid_signature, copy invalid_pubkey, x""), 9006); + // invalid signature, valid pubkey + assert!(!Signature::ed25519_verify(copy short_signature, copy valid_pubkey, x""), 9007); + assert!(!Signature::ed25519_verify(copy long_signature, copy valid_pubkey, x""), 9008); + + // valid (lengthwise) signature, valid pubkey, but signature doesn't match message + assert!(!Signature::ed25519_verify(copy valid_signature, copy valid_pubkey, x""), 9009); + + // all three valid + assert!(Signature::ed25519_verify(valid_signature, pubkey, message), 9010); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/TransactionFeeTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/TransactionFeeTests.move new file mode 100644 index 000000000..deb26c34c --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/TransactionFeeTests.move @@ -0,0 +1,18 @@ +#[test_only] +module DiemFramework::TransactionFeeTests { + use DiemFramework::TransactionFee; + use DiemFramework::Genesis; + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun cannot_initialize_after_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + TransactionFee::initialize(&tc); + } + + #[test(account = @0x100)] + #[expected_failure(abort_code = 258, location = DiemFramework::CoreAddresses)] + fun cannot_initialize_as_non_tc(account: signer) { + TransactionFee::initialize(&account); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/ValidatorConfigTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/ValidatorConfigTests.move new file mode 100644 index 000000000..b46e9d281 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/ValidatorConfigTests.move @@ -0,0 +1,218 @@ +#[test_only] +module DiemFramework::ValidatorConfigTests { + use DiemFramework::ValidatorConfig as VC; + use DiemFramework::ValidatorOperatorConfig as VOC; + use DiemFramework::Roles; + use DiemFramework::Genesis; + use std::unit_test; + use std::vector; + use std::signer; + + const VALID_PUBKEY: vector = x"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + + fun signer_at(index: u64): signer { + let signers = unit_test::create_signers_for_testing(index + 1); + vector::pop_back(&mut signers) + } + + #[test] + #[expected_failure(abort_code = 257, location = DiemFramework::DiemTimestamp)] + fun publish_pre_genesis() { + let s = signer_at(0); + VC::publish(&s, &s, x""); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun publish_post_genesis_non_dr(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = signer_at(0); + VC::publish(&s, &tc, x""); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 5, location = DiemFramework::Roles)] + fun publish_post_genesis_non_validator(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = signer_at(0); + VC::publish(&s, &dr, x""); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun publish_post_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = signer_at(0); + Roles::new_validator_role(&dr, &s); + VC::publish(&s, &dr, x""); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 6, location = VC)] + fun publish_post_genesis_double_publish(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = signer_at(0); + Roles::new_validator_role(&dr, &s); + VC::publish(&s, &dr, x""); + VC::publish(&s, &dr, x""); + } + + #[test] + #[expected_failure(abort_code = 5, location = DiemFramework::Roles)] + fun set_operator_not_validator() { + let s = signer_at(0); + VC::set_operator(&s, @0x1); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 775, location = VC)] + fun set_operator_not_operator(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = signer_at(0); + Roles::new_validator_role(&dr, &s); + VC::set_operator(&s, @0x1); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 5, location = DiemFramework::Roles)] + fun set_operator_no_validator_config_has_role(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let operator = signer_at(1); + Roles::new_validator_role(&dr, &validator); + VOC::publish(&operator, &dr, x""); + VC::set_operator(&validator, signer::address_of(&operator)); + } + + #[test_only] + fun set_operator(dr: &signer, validator: &signer, operator: &signer) { + let operator_addr = signer::address_of(operator); + Roles::new_validator_role(dr, validator); + Roles::new_validator_operator_role(dr, operator); + VC::publish(validator, dr, x"FF"); + VOC::publish(operator, dr, x"FFFF"); + VC::set_operator(validator, operator_addr); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun set_operator_correct(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let operator = signer_at(1); + let operator_addr = signer::address_of(&operator); + let validator_addr = signer::address_of(&validator); + set_operator(&dr, &validator, &operator); + assert!(VC::get_operator(validator_addr) == operator_addr, 0); + } + + #[test] + #[expected_failure(abort_code = 5, location = DiemFramework::Roles)] + fun remove_operator_not_validator() { + let s = signer_at(0); + VC::remove_operator(&s); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 5, location = VC)] + fun remove_operator_no_config(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = signer_at(0); + Roles::new_validator_role(&dr, &s); + VC::remove_operator(&s); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 7, location = VC)] + fun remove_operator_correct(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let operator = signer_at(1); + let operator_addr = signer::address_of(&operator); + let validator_addr = signer::address_of(&validator); + set_operator(&dr, &validator, &operator); + assert!(VC::get_operator(validator_addr) == operator_addr, 0); + VC::remove_operator(&validator); + VC::get_operator(validator_addr); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 263, location = VC)] + fun set_config_operator_neq_operator(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let operator = signer_at(1); + let other_operator = signer_at(2); + let validator_addr = signer::address_of(&validator); + set_operator(&dr, &validator, &operator); + VC::set_config(&other_operator, validator_addr, x"", x"", x"") + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 519, location = VC)] + fun set_config_invalid_consensus_pubkey(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let operator = signer_at(1); + let validator_addr = signer::address_of(&validator); + set_operator(&dr, &validator, &operator); + VC::set_config(&operator, validator_addr, x"", x"", x"") + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun set_config_correct(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let operator = signer_at(1); + let validator_addr = signer::address_of(&validator); + let operator_addr = signer::address_of(&operator); + set_operator(&dr, &validator, &operator); + VC::set_config(&operator, validator_addr, VALID_PUBKEY, x"AA", x"BB"); + assert!(VC::is_valid(validator_addr), 0); + assert!(VC::get_human_name(validator_addr) == x"FF", 1); + assert!(VC::get_operator(validator_addr) == operator_addr, 2); + let config = VC::get_config(validator_addr); + assert!(*VC::get_consensus_pubkey(&config) == VALID_PUBKEY, 3); + assert!(*VC::get_validator_network_addresses(&config) == x"AA", 4); + } + + #[test] + #[expected_failure(abort_code = 5, location = VC)] + fun get_config_not_validator() { + VC::get_config(@0x1); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 7, location = VC)] + fun get_config_not_set(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let operator = signer_at(1); + let validator_addr = signer::address_of(&validator); + set_operator(&dr, &validator, &operator); + VC::get_config(validator_addr); + } + + #[test] + #[expected_failure(abort_code = 5, location = VC)] + fun get_human_name_not_validator() { + VC::get_human_name(@0x1); + } + + #[test] + #[expected_failure(abort_code = 5, location = VC)] + fun get_operator_not_validator() { + VC::get_operator(@0x1); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 7, location = VC)] + fun get_operator_not_set(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let validator = signer_at(0); + let validator_addr = signer::address_of(&validator); + + Roles::new_validator_role(&dr, &validator); + VC::publish(&validator, &dr, x"FF"); + + VC::get_operator(validator_addr); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/ValidatorOperatorConfigTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/ValidatorOperatorConfigTests.move new file mode 100644 index 000000000..9ce2c05a9 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/ValidatorOperatorConfigTests.move @@ -0,0 +1,70 @@ +#[test_only] +module DiemFramework::ValidatorOperatorConfigTests { + use DiemFramework::ValidatorOperatorConfig as VOC; + use DiemFramework::Roles; + use DiemFramework::Genesis; + use std::unit_test; + use std::vector; + use std::signer; + + fun get_signer(): signer { + vector::pop_back(&mut unit_test::create_signers_for_testing(1)) + } + + #[test] + #[expected_failure(abort_code = 257, location = DiemFramework::DiemTimestamp)] + fun publish_pre_genesis() { + let s = get_signer(); + VOC::publish(&s, &s, x""); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 2, location = DiemFramework::CoreAddresses)] + fun publish_post_genesis_non_dr(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = get_signer(); + VOC::publish(&s, &tc, x""); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 5, location = DiemFramework::Roles)] + fun publish_post_genesis_non_validator_operator(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = get_signer(); + VOC::publish(&s, &dr, x""); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun publish_post_genesis(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = get_signer(); + Roles::new_validator_operator_role(&dr, &s); + VOC::publish(&s, &dr, x""); + assert!(VOC::has_validator_operator_config(signer::address_of(&s)), 0); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + #[expected_failure(abort_code = 6, location = VOC)] + fun publish_post_genesis_double_publish(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = get_signer(); + Roles::new_validator_operator_role(&dr, &s); + VOC::publish(&s, &dr, x""); + VOC::publish(&s, &dr, x""); + } + + #[test] + #[expected_failure(abort_code = 5, location = VOC)] + fun get_human_name_not_validator_operator() { + VOC::get_human_name(@0x1); + } + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot)] + fun get_human_name(tc: signer, dr: signer) { + Genesis::setup(&dr, &tc); + let s = get_signer(); + Roles::new_validator_operator_role(&dr, &s); + VOC::publish(&s, &dr, b"test"); + assert!(VOC::get_human_name(signer::address_of(&s)) == b"test", 0); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/WalletModuleTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/WalletModuleTests.move new file mode 100644 index 000000000..f34355155 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/WalletModuleTests.move @@ -0,0 +1,211 @@ +#[test_only] +module DiemFramework::ApprovalGroup { + use DiemFramework::Signature; + + struct ApprovalGroup has store { + // we do not have collection support in Move now, so illustrate + // using 2 out-of 3 + + // for simplicity just use the plain public key here. We could + // also use the hash here as how auth key works + pk1: vector, + pk2: vector, + pk3: vector, + + // the threshold policy + threshold: u64, + + // Recipient address allowlist policy ... + } + + // create a new approval group + public fun create( + pk1: vector, + pk2: vector, + pk3: vector, + ): ApprovalGroup { + ApprovalGroup {pk1, pk2, pk3, threshold: 2} + } + + // helper function to evaluate the threshold policy + fun verify_sig( + group: &ApprovalGroup, + pk: vector, + sig: vector, + hash: vector, + ): bool { + ( + copy pk == *&group.pk1 || + copy pk == *&group.pk2 || + copy pk == *&group.pk3 + ) && Signature::ed25519_verify(sig, pk, hash) + } + + // evaluate whether the approval group can exercise its authority + // right now only the threshold policy is checked + public fun has_authority( + group: &ApprovalGroup, + pk1: vector, + sig1: vector, + pk2: vector, + sig2: vector, + hash: vector, + ): bool { + assert!(copy pk1 != copy pk2, 1000); + let result1 = verify_sig(group, pk1, sig1, copy hash); + let result2 = verify_sig(group, pk2, sig2, hash); + result1 && result2 + } +} + +#[test_only] +module DiemFramework::ColdWallet { + use DiemFramework::XUS::XUS; + use std::hash; + use std::bcs; + use DiemFramework::Diem; + use std::vector; + use std::signer; + use DiemFramework::ApprovalGroup; + + struct ColdWallet has key { + balance: Diem::Diem, + sequence_num: u64, + genesis_group: ApprovalGroup::ApprovalGroup, + } + + // This struct is unused, only intended to define the format of a transaction + // the serialization of the transaction is the concatnation of all the fields + struct Transaction { + // The address that is going to be paid + payee: address, + // The amount of Diem sent + amount: u64 + } + + // create a new ColdWallet with a default genesis group + public fun create( + account: &signer, + genesis_group: ApprovalGroup::ApprovalGroup, + ) { + let zero_balance = Diem::zero(); + let wallet = ColdWallet { + balance: zero_balance, + sequence_num: 0, + genesis_group, + }; + move_to(account, wallet); + } + + public fun publish(account: &signer, self: ColdWallet) { + move_to(account, self); + } + + // deposit money into a payee's cold wallet + public fun deposit( + payee: address, + to_deposit: Diem::Diem, + ) acquires ColdWallet { + // Load the payee's account + let payee_wallet_ref = borrow_global_mut(payee); + // Deposit the `to_deposit` coin + Diem::deposit(&mut payee_wallet_ref.balance, to_deposit); + } + + // helper to get the expected serialization of a transaction + // serialization format: 'prefix' || payee_address || amount || sequence_number + fun get_transaction_bytes( + payer: address, + payee: address, + amount: u64, + wallet: &mut ColdWallet, + ): vector { + // TODO: consider moving into resource + // TODO: Move doesn't support string now. As a workaround, + // TODO: the prefix is the hex encoding of "coldwallet.transaction" + let constant = x"636F6C6477616C6C65742E7472616E73616374696F6E"; + let payer_bytes = bcs::to_bytes(&payer); + + let transaction_bytes = copy payer_bytes; + vector::append(&mut transaction_bytes, constant); + + let payee_bytes = bcs::to_bytes(&payee); + let amount_bytes = bcs::to_bytes(&amount); + let seq_bytes = bcs::to_bytes(&wallet.sequence_num); + + vector::append(&mut transaction_bytes, payee_bytes); + vector::append(&mut transaction_bytes, amount_bytes); + vector::append(&mut transaction_bytes, seq_bytes); + + transaction_bytes + } + + // withdraw money from this wallet, and send to a payee account + // Note that this implementation moves the fund into the payee's + // Diem account, without assuming there's a cold wallet module + // under that account + public fun withdraw_from_payer( + payer_: &signer, + payee: address, + amount: u64, + pk1: vector, + sig1: vector, + pk2: vector, + sig2: vector + ) acquires ColdWallet { + let payer = signer::address_of(payer_); + let payer_ref = borrow_global_mut(payer); + let account_balance = Diem::value(&payer_ref.balance); + assert!(amount <= account_balance, 1001); + + // obtain the expected serialization of the transaction struct + let transaction_bytes = get_transaction_bytes( + payer, + payee, + amount, + payer_ref, + ); + + + let hash = hash::sha3_256(transaction_bytes); + let has_authority = ApprovalGroup::has_authority( + &payer_ref.genesis_group, + pk1, + sig1, + pk2, + sig2, + hash, + ); + // check to see if genesis group has authority to approve + if (has_authority) { + // bump the sequence number + payer_ref.sequence_num = payer_ref.sequence_num + 1; + + let withdraw_amount = Diem::withdraw(&mut payer_ref.balance, amount); + // DiemAccount no longer has this API + //DiemAccount::deposit(payer_, payee, withdraw_amount); + Diem::destroy_zero(withdraw_amount); + }; + } +} + +#[test_only] +module DiemFramework::WalletModuleTests { + use DiemFramework::Genesis; + use DiemFramework::DiemAccount; + use DiemFramework::XUS::XUS; + use std::signer; + + use DiemFramework::ApprovalGroup; + use DiemFramework::ColdWallet; + + // private-key: 2f2bbeb071948c4ca586b0fa0f3663520fc3053056e79955059520d626117cdb + #[test(dr = @DiemRoot, tc = @TreasuryCompliance, account = @0xc2422587142d78bdf5a8068b8f9a2859)] + fun wallet_module_test(dr: signer, tc: signer, account: signer) { + Genesis::setup(&dr, &tc); + DiemAccount::create_parent_vasp_account(&tc, signer::address_of(&account), x"355b32f571f894cfd431ab40dc950037", b"", false); + + let genesis_group = ApprovalGroup::create(x"1234", x"5678", x"abc123"); + ColdWallet::create(&account, genesis_group); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/XUSTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/XUSTests.move new file mode 100644 index 000000000..e69b265aa --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/DPN/tests/XUSTests.move @@ -0,0 +1,12 @@ +#[test_only] +module DiemFramework::XUSTests { + use DiemFramework::XUS; + use DiemFramework::Genesis; + + #[test(tc = @TreasuryCompliance, dr = @DiemRoot, account = @0x100)] + #[expected_failure(abort_code = 1, location = DiemFramework::DiemTimestamp)] + fun cannot_recreate_market_cap(tc: signer, dr: signer, account: signer) { + Genesis::setup(&dr, &tc); + XUS::initialize(&account, &account); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/Move.toml b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/Move.toml new file mode 100644 index 000000000..ce44f401a --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "DiemCoreFramework" +version = "1.5.0" + +[addresses] +std = "0x1" +VMReserved = "0x0" +CoreFramework = "0x1" +CoreResources = "0xA550C18" + +[dependencies] +MoveStdlib = { local = "../../../../../move-stdlib" } +MoveNursery = { local = "../../../../../move-stdlib/nursery" } diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/README.md b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/README.md new file mode 100644 index 000000000..071c27058 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/README.md @@ -0,0 +1,42 @@ +This folder contains a Move package consisting of core Move modules defining functionalities needed by +any Diem-based blockchains. To start your own Diem-based blockchain, you can create a Move package that +depends on this core package and write your own wrapper modules for the account module as well as the +on-chain configuration modules. [`experimental` folder](../experimental) provides an example of such +Move package. + +Next we briefly describe how to write the wrapper modules and how Move's powerful type system can provide flexibility +as well as safety for your chain. + +You will need to write wrapper modules for the following core modules: +- Account +- CoreGenesis +- DiemConsensusConfig +- DiemSystem +- DiemVersion +- DiemVMConfig +- ParallelExecutionConfig +- ValidatorConfig +- ValidatorOperatorConfig + + +Every module in this list contains the following resources and functions: +- A chain marker resource with a `phantom T` type parameter +- An initialization function that has to be called during chain-specific genesis and publishes a chain marker resource under + `@CoreResources` address as well as any relevant configuration resources +- At least one setter function that requires a `Cap` as parameter and modifies the configuration resource(s). + And at the beginning of the function we check the existence of the chain marker resource. + +#### Why is the chain marker resource needed? + +We want to provide the safety guarantee that only the authorized wrapper module can define access +control policies for the resources. Therefore, we need to make sure that only the wrapper module can call the public +setter functions. However, we are designing for wrapper modules that don't even exist right now, so we have to somehow +"register" the wrapper module at the chain-specific genesis. The solution to this question is the chain marker resource. +This resource has a phantom type parameter that should be instantiated with a type owned by the wrapper module such as +`ExperimentalVersion` resource. Each setter function requires a capability parameter instantiated with this type. Since +the acquisition of this capability requires a value of this witness type and this type is owned by the wrapper module, +we know for sure that only the wrapper module can decide who or which module is allowed to modify the configurations. + +#### How to write wrapper modules? + +Read `DiemVersion.move` and then `ExperimentalVersion.move` to get the idea. diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/Account.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/Account.move new file mode 100644 index 000000000..6a1f9b726 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/Account.move @@ -0,0 +1,233 @@ +module CoreFramework::Account { + use std::bcs; + use std::errors; + use std::signer; + use std::hash; + use std::vector; + use CoreFramework::ChainId; + use CoreFramework::DiemConfig; + use CoreFramework::SystemAddresses; + + /// Resource representing an account. + struct Account has key, store { + authentication_key: vector, + sequence_number: u64, + self_address: address, + } + + /// A marker resource that registers the type `T` as the system marker for BasicAccount at genesis. + struct Marker has key { } + + /// This holds information that will be picked up by the VM to call the + /// correct chain-specific prologue and epilogue functions + struct ChainSpecificAccountInfo has key { + module_addr: address, + module_name: vector, + script_prologue_name: vector, + module_prologue_name: vector, + writeset_prologue_name: vector, + multi_agent_prologue_name: vector, + user_epilogue_name: vector, + writeset_epilogue_name: vector, + currency_code_required: bool, + } + + const MAX_U64: u128 = 18446744073709551615; + + /// Account already existed + const EACCOUNT: u64 = 0; + /// Sequence number exceeded the maximum value for a u64 + const ESEQUENCE_NUMBER_TOO_BIG: u64 = 1; + /// The address provided didn't match the `CoreFramework` address. + const ENOT_CORE_FRAMEWORK: u64 = 2; + /// The marker type provided is not the registered type for `Account`. + const ENOT_MARKER_TYPE: u64 = 3; + /// The provided authentication had an invalid length + const EMALFORMED_AUTHENTICATION_KEY: u64 = 4; + + const PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY: u64 = 1001; + const PROLOGUE_ESEQUENCE_NUMBER_TOO_OLD: u64 = 1002; + const PROLOGUE_ESEQUENCE_NUMBER_TOO_NEW: u64 = 1003; + const PROLOGUE_EACCOUNT_DNE: u64 = 1004; + const PROLOGUE_EBAD_CHAIN_ID: u64 = 1005; + const PROLOGUE_ESEQUENCE_NUMBER_TOO_BIG: u64 = 1006; + + native fun create_signer(addr: address): signer; + + public fun initialize(account: &signer, + module_addr: address, + module_name: vector, + script_prologue_name: vector, + module_prologue_name: vector, + writeset_prologue_name: vector, + multi_agent_prologue_name: vector, + user_epilogue_name: vector, + writeset_epilogue_name: vector, + currency_code_required: bool, + ) { + assert!(signer::address_of(account) == @CoreResources, errors::requires_address(ENOT_CORE_FRAMEWORK)); + move_to(account, Marker {}); + move_to(account, ChainSpecificAccountInfo { + module_addr, + module_name, + script_prologue_name, + module_prologue_name, + writeset_prologue_name, + multi_agent_prologue_name, + user_epilogue_name, + writeset_epilogue_name, + currency_code_required, + }); + } + + fun assert_is_marker() { + assert!(exists>(@CoreResources), errors::invalid_argument(ENOT_MARKER_TYPE)) + } + + /// Construct an authentication key, aborting if the prefix is not valid. + fun create_authentication_key(account: &signer, auth_key_prefix: vector): vector { + let authentication_key = auth_key_prefix; + vector::append( + &mut authentication_key, bcs::to_bytes(signer::borrow_address(account)) + ); + /* + assert!( + vector::length(&authentication_key) == 32, + errors::invalid_argument(EMALFORMED_AUTHENTICATION_KEY) + ); + */ + authentication_key + } + // spec create_authentication_key { + // /// The specification of this function is abstracted to avoid the complexity of + // /// vector concatenation of serialization results. The actual value of the key + // /// is assumed to be irrelevant for callers. Instead the uninterpreted function + // /// `spec_abstract_create_authentication_key` is used to represent the key value. + // /// The aborts behavior is, however, preserved: the caller must provide a + // /// key prefix of a specific length. + // pragma opaque; + // include [abstract] CreateAuthenticationKeyAbortsIf; + // ensures [abstract] + // result == spec_abstract_create_authentication_key(auth_key_prefix) && + // len(result) == 32; + // } + // spec schema CreateAuthenticationKeyAbortsIf { + // auth_key_prefix: vector; + // aborts_if 16 + len(auth_key_prefix) != 32 with Errors::INVALID_ARGUMENT; + // } + // spec fun spec_abstract_create_authentication_key(auth_key_prefix: vector): vector; + + /// Publishes a new `Account` resource under `new_address`. + /// A signer representing `new_address` is returned. This way, the caller of this function + /// can publish additional resources under `new_address`. + /// The `_witness` guarantees that owner the registered caller of this function can call it. + /// authentication key returned is `auth_key_prefix` | `fresh_address`. + public fun create_account( + new_address: address, + authentication_key_prefix: vector, + _witness: &T, + ): (signer, vector) { + assert_is_marker(); + // there cannot be an Account resource under new_addr already. + assert!(!exists(new_address), errors::already_published(EACCOUNT)); + + let new_account = create_signer(new_address); + let authentication_key = create_authentication_key(&new_account, authentication_key_prefix); + move_to( + &new_account, + Account { + authentication_key: copy authentication_key, + sequence_number: 0, + self_address: new_address, + } + ); + + (new_account, authentication_key) + } + + public fun exists_at(addr: address): bool { + exists(addr) + } + + public fun get_sequence_number(addr: address) : u64 acquires Account { + borrow_global(addr).sequence_number + } + + public fun get_authentication_key(addr: address) : vector acquires Account { + *&borrow_global(addr).authentication_key + } + + public fun rotate_authentication_key( + account: &signer, + new_auth_key: vector, + ) acquires Account { + let addr = signer::address_of(account); + assert!(exists_at(addr), errors::not_published(EACCOUNT)); + assert!( + vector::length(&new_auth_key) == 32, + errors::invalid_argument(EMALFORMED_AUTHENTICATION_KEY) + ); + let account_resource = borrow_global_mut(addr); + account_resource.authentication_key = new_auth_key; + } + + public fun prologue( + account: &signer, + txn_sequence_number: u64, + txn_public_key: vector, + chain_id: u8, + ) acquires Account { + let transaction_sender = signer::address_of(account); + assert!(ChainId::get() == chain_id, errors::invalid_argument(PROLOGUE_EBAD_CHAIN_ID)); + assert!(exists(transaction_sender), errors::invalid_argument(PROLOGUE_EACCOUNT_DNE)); + let sender_account = borrow_global(transaction_sender); + assert!( + hash::sha3_256(txn_public_key) == *&sender_account.authentication_key, + errors::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), + ); + assert!( + (txn_sequence_number as u128) < MAX_U64, + errors::limit_exceeded(PROLOGUE_ESEQUENCE_NUMBER_TOO_BIG) + ); + + assert!( + txn_sequence_number >= sender_account.sequence_number, + errors::invalid_argument(PROLOGUE_ESEQUENCE_NUMBER_TOO_OLD) + ); + + // [PCA12]: Check that the transaction's sequence number matches the + // current sequence number. Otherwise sequence number is too new by [PCA11]. + assert!( + txn_sequence_number == sender_account.sequence_number, + errors::invalid_argument(PROLOGUE_ESEQUENCE_NUMBER_TOO_NEW) + ); + } + + /// Epilogue function is run after a transaction is successfully executed. + /// Called by the Adaptor + public fun epilogue(account: &signer, _witness: &T) acquires Account { + assert_is_marker(); + let addr = signer::address_of(account); + let old_sequence_number = get_sequence_number(addr); + + assert!( + (old_sequence_number as u128) < MAX_U64, + errors::limit_exceeded(ESEQUENCE_NUMBER_TOO_BIG) + ); + + // Increment sequence number + let account_resource = borrow_global_mut(addr); + account_resource.sequence_number = old_sequence_number + 1; + } + + /// Epilogue function called after a successful writeset transaction, which can only be sent by @CoreResources. + public fun writeset_epilogue( + account: &signer, + should_trigger_reconfiguration: bool, + witness: &T + ) acquires Account { + SystemAddresses::assert_core_resource(account); + epilogue(account, witness); + if (should_trigger_reconfiguration) DiemConfig::reconfigure(); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/ChainId.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/ChainId.move new file mode 100644 index 000000000..549aef2a1 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/ChainId.move @@ -0,0 +1,30 @@ +/// The chain id distinguishes between different chains (e.g., testnet and the main Diem network). +/// One important role is to prevent transactions intended for one chain from being executed on another. +/// This code provides a container for storing a chain id and functions to initialize and get it. +module CoreFramework::ChainId { + use CoreFramework::SystemAddresses; + use CoreFramework::DiemTimestamp; + use std::errors; + use std::signer; + + struct ChainId has key { + id: u8 + } + + /// The `ChainId` resource was not in the required state + const ECHAIN_ID: u64 = 0; + + /// Publish the chain ID `id` of this Diem instance under the SystemAddresses address + public fun initialize(account: &signer, id: u8) { + DiemTimestamp::assert_genesis(); + SystemAddresses::assert_core_resource(account); + assert!(!exists(signer::address_of(account)), errors::already_published(ECHAIN_ID)); + move_to(account, ChainId { id }) + } + + /// Return the chain ID of this Diem instance + public fun get(): u8 acquires ChainId { + DiemTimestamp::assert_operating(); + borrow_global(@CoreResources).id + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/CoreGenesis.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/CoreGenesis.move new file mode 100644 index 000000000..6fbda2a37 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/CoreGenesis.move @@ -0,0 +1,14 @@ +module CoreFramework::CoreGenesis { + use CoreFramework::ChainId; + use CoreFramework::DiemBlock; + use CoreFramework::DiemConfig; + use CoreFramework::DiemTimestamp; + + /// This can only be called once successfully, since after the first call time will have started. + public fun init(core_resource_account: &signer, chain_id: u8) { + ChainId::initialize(core_resource_account, chain_id); + DiemConfig::initialize(core_resource_account); + DiemBlock::initialize_block_metadata(core_resource_account); + DiemTimestamp::set_time_has_started(core_resource_account); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemBlock.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemBlock.move new file mode 100644 index 000000000..1284832fe --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemBlock.move @@ -0,0 +1,90 @@ +/// This module defines a struct storing the metadata of the block and new block events. +module CoreFramework::DiemBlock { + use std::errors; + use std::event; + use CoreFramework::DiemSystem; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + struct BlockMetadata has key { + /// Height of the current block + height: u64, + /// Handle where events with the time of new blocks are emitted + new_block_events: event::EventHandle, + } + + struct NewBlockEvent has drop, store { + round: u64, + proposer: address, + previous_block_votes: vector
, + + /// On-chain time during he block at the given height + time_microseconds: u64, + } + + /// The `BlockMetadata` resource is in an invalid state + const EBLOCK_METADATA: u64 = 0; + /// An invalid signer was provided. Expected the signer to be the VM or a Validator. + const EVM_OR_VALIDATOR: u64 = 1; + + /// This can only be invoked by the Association address, and only a single time. + /// Currently, it is invoked in the genesis transaction + public fun initialize_block_metadata(account: &signer) { + DiemTimestamp::assert_genesis(); + // Operational constraint, only callable by the Association address + SystemAddresses::assert_core_resource(account); + + assert!(!is_initialized(), errors::already_published(EBLOCK_METADATA)); + move_to( + account, + BlockMetadata { + height: 0, + new_block_events: event::new_event_handle(account), + } + ); + } + + /// Helper function to determine whether this module has been initialized. + fun is_initialized(): bool { + exists(@CoreResources) + } + + /// Set the metadata for the current block. + /// The runtime always runs this before executing the transactions in a block. + fun block_prologue( + vm: signer, + round: u64, + timestamp: u64, + previous_block_votes: vector
, + proposer: address + ) acquires BlockMetadata { + DiemTimestamp::assert_operating(); + // Operational constraint: can only be invoked by the VM. + SystemAddresses::assert_vm(&vm); + + // Authorization + assert!( + proposer == @VMReserved || DiemSystem::is_validator(proposer), + errors::requires_address(EVM_OR_VALIDATOR) + ); + + let block_metadata_ref = borrow_global_mut(@CoreResources); + DiemTimestamp::update_global_time(&vm, proposer, timestamp); + block_metadata_ref.height = block_metadata_ref.height + 1; + event::emit_event( + &mut block_metadata_ref.new_block_events, + NewBlockEvent { + round, + proposer, + previous_block_votes, + time_microseconds: timestamp, + } + ); + } + + /// Get the current block height + public fun get_current_block_height(): u64 acquires BlockMetadata { + assert!(is_initialized(), errors::not_published(EBLOCK_METADATA)); + borrow_global(@CoreResources).height + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemConfig.move new file mode 100644 index 000000000..6a8ef973a --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemConfig.move @@ -0,0 +1,145 @@ +/// Publishes configuration information for validators, and issues reconfiguration events +/// to synchronize configuration changes for the validators. +module CoreFramework::DiemConfig { + use std::errors; + use std::event; + use std::signer; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + friend CoreFramework::Account; + friend CoreFramework::DiemConsensusConfig; + friend CoreFramework::DiemSystem; + friend CoreFramework::DiemVersion; + friend CoreFramework::DiemVMConfig; + friend CoreFramework::ParallelExecutionConfig; + + /// Event that signals DiemBFT algorithm to start a new epoch, + /// with new configuration information. This is also called a + /// "reconfiguration event" + struct NewEpochEvent has drop, store { + epoch: u64, + } + + /// Holds information about state of reconfiguration + struct Configuration has key { + /// Epoch number + epoch: u64, + /// Time of last reconfiguration. Only changes on reconfiguration events. + last_reconfiguration_time: u64, + /// Event handle for reconfiguration events + events: event::EventHandle, + } + + /// Reconfiguration disabled if this resource occurs under LibraRoot. + struct DisableReconfiguration has key {} + + /// The `Configuration` resource is in an invalid state + const ECONFIGURATION: u64 = 0; + /// A `DiemConfig` resource is in an invalid state + const EDIEM_CONFIG: u64 = 1; + /// A `ModifyConfigCapability` is in a different state than was expected + const EMODIFY_CAPABILITY: u64 = 2; + /// An invalid block time was encountered. + const EINVALID_BLOCK_TIME: u64 = 3; + /// The largest possible u64 value + const MAX_U64: u64 = 18446744073709551615; + + /// Publishes `Configuration` resource. Can only be invoked by Diem root, and only a single time in Genesis. + public fun initialize( + account: &signer, + ) { + DiemTimestamp::assert_genesis(); + SystemAddresses::assert_core_resource(account); + assert!(!exists(@CoreResources), errors::already_published(ECONFIGURATION)); + move_to( + account, + Configuration { + epoch: 0, + last_reconfiguration_time: 0, + events: event::new_event_handle(account), + } + ); + } + + /// Private function to temporarily halt reconfiguration. + /// This function should only be used for offline WriteSet generation purpose and should never be invoked on chain. + fun disable_reconfiguration(account: &signer) { + SystemAddresses::assert_core_resource(account); + assert!(reconfiguration_enabled(), errors::invalid_state(ECONFIGURATION)); + move_to(account, DisableReconfiguration {} ) + } + + /// Private function to resume reconfiguration. + /// This function should only be used for offline WriteSet generation purpose and should never be invoked on chain. + fun enable_reconfiguration(account: &signer) acquires DisableReconfiguration { + SystemAddresses::assert_core_resource(account); + + assert!(!reconfiguration_enabled(), errors::invalid_state(ECONFIGURATION)); + DisableReconfiguration {} = move_from(signer::address_of(account)); + } + + fun reconfiguration_enabled(): bool { + !exists(@CoreResources) + } + + /// Signal validators to start using new configuration. Must be called from friend config modules. + public(friend) fun reconfigure() acquires Configuration { + reconfigure_(); + } + + /// Private function to do reconfiguration. Updates reconfiguration status resource + /// `Configuration` and emits a `NewEpochEvent` + fun reconfigure_() acquires Configuration { + // Do not do anything if genesis has not finished. + if (DiemTimestamp::is_genesis() || DiemTimestamp::now_microseconds() == 0 || !reconfiguration_enabled()) { + return () + }; + + let config_ref = borrow_global_mut(@CoreResources); + let current_time = DiemTimestamp::now_microseconds(); + + // Do not do anything if a reconfiguration event is already emitted within this transaction. + // + // This is OK because: + // - The time changes in every non-empty block + // - A block automatically ends after a transaction that emits a reconfiguration event, which is guaranteed by + // DiemVM spec that all transactions comming after a reconfiguration transaction will be returned as Retry + // status. + // - Each transaction must emit at most one reconfiguration event + // + // Thus, this check ensures that a transaction that does multiple "reconfiguration required" actions emits only + // one reconfiguration event. + // + if (current_time == config_ref.last_reconfiguration_time) { + return + }; + + assert!(current_time > config_ref.last_reconfiguration_time, errors::invalid_state(EINVALID_BLOCK_TIME)); + config_ref.last_reconfiguration_time = current_time; + config_ref.epoch = config_ref.epoch + 1; + + event::emit_event( + &mut config_ref.events, + NewEpochEvent { + epoch: config_ref.epoch, + }, + ); + } + + /// Emit a `NewEpochEvent` event. This function will be invoked by genesis directly to generate the very first + /// reconfiguration event. + fun emit_genesis_reconfiguration_event() acquires Configuration { + assert!(exists(@CoreResources), errors::not_published(ECONFIGURATION)); + let config_ref = borrow_global_mut(@CoreResources); + assert!(config_ref.epoch == 0 && config_ref.last_reconfiguration_time == 0, errors::invalid_state(ECONFIGURATION)); + config_ref.epoch = 1; + + event::emit_event( + &mut config_ref.events, + NewEpochEvent { + epoch: config_ref.epoch, + }, + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemTimestamp.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemTimestamp.move new file mode 100644 index 000000000..d24ce999e --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/DiemTimestamp.move @@ -0,0 +1,195 @@ +/// This module keeps a global wall clock that stores the current Unix time in microseconds. +/// It interacts with the other modules in the following ways: +/// +/// * Genesis: to initialize the timestamp +/// * VASP: to keep track of when credentials expire +/// * DiemSystem, DiemAccount, DiemConfig: to check if the current state is in the genesis state +/// * DiemBlock: to reach consensus on the global wall clock time +/// * AccountLimits: to limit the time of account limits +/// +/// This module moreover enables code to assert that it is running in genesis (`Self::assert_genesis`) or after +/// genesis (`Self::assert_operating`). These are essentially distinct states of the system. Specifically, +/// if `Self::assert_operating` succeeds, assumptions about invariants over the global state can be made +/// which reflect that the system has been successfully initialized. +module CoreFramework::DiemTimestamp { + use CoreFramework::SystemAddresses; + use std::signer; + use std::errors; + + friend CoreFramework::CoreGenesis; + + /// A singleton resource holding the current Unix time in microseconds + struct CurrentTimeMicroseconds has key { + microseconds: u64, + } + + /// Conversion factor between seconds and microseconds + const MICRO_CONVERSION_FACTOR: u64 = 1000000; + + /// The blockchain is not in the genesis state anymore + const ENOT_GENESIS: u64 = 0; + /// The blockchain is not in an operating state yet + const ENOT_OPERATING: u64 = 1; + /// An invalid timestamp was provided + const ETIMESTAMP: u64 = 2; + + /// Marks that time has started and genesis has finished. This can only be called from genesis and with the root + /// account. + public(friend) fun set_time_has_started(dr_account: &signer) { + assert_genesis(); + SystemAddresses::assert_core_resource(dr_account); + let timer = CurrentTimeMicroseconds { microseconds: 0 }; + move_to(dr_account, timer); + } + spec set_time_has_started { + /// This function can't be verified on its own and has to be verified in the context of Genesis execution. + /// + /// After time has started, all invariants guarded by `DiemTimestamp::is_operating` will become activated + /// and need to hold. + pragma delegate_invariants_to_caller; + include AbortsIfNotGenesis; + include SystemAddresses::AbortsIfNotCoreResource{addr: signer::address_of(dr_account)}; + ensures is_operating(); + } + + // TODO: this is for both df-cli and the unit-test for df + // - df-cli, as a few test cases in df-cli uses a customized genesis module and that module needs to invoke + // `set_time_has_started` in order to complete the genesis process. Until we find a way to solve this issue, this + // temporary function will stay here. + // - this is also needed for diem-framework unit test `DiemTimestampTests`. And once the above issue for df-cli is + // resolved, we can mark this function #[test_only] + public fun set_time_has_started_for_testing(dr_account: &signer) { + set_time_has_started(dr_account); + } + spec set_time_has_started_for_testing { + pragma verify = false; + } + + /// Updates the wall clock time by consensus. Requires VM privilege and will be invoked during block prologue. + public fun update_global_time( + account: &signer, + proposer: address, + timestamp: u64 + ) acquires CurrentTimeMicroseconds { + assert_operating(); + // Can only be invoked by DiemVM signer. + SystemAddresses::assert_vm(account); + + let global_timer = borrow_global_mut(@CoreResources); + let now = global_timer.microseconds; + if (proposer == @VMReserved) { + // NIL block with null address as proposer. Timestamp must be equal. + assert!(now == timestamp, errors::invalid_argument(ETIMESTAMP)); + } else { + // Normal block. Time must advance + assert!(now < timestamp, errors::invalid_argument(ETIMESTAMP)); + }; + global_timer.microseconds = timestamp; + } + spec update_global_time { + pragma opaque; + modifies global(@CoreResources); + + let now = spec_now_microseconds(); + let post post_now = spec_now_microseconds(); + + /// Conditions unique for abstract and concrete version of this function. + include AbortsIfNotOperating; + include SystemAddresses::AbortsIfNotVM; + ensures post_now == timestamp; + + /// Conditions we only check for the implementation, but do not pass to the caller. + aborts_if [concrete] + (if (proposer == @VMReserved) { + now != timestamp + } else { + now >= timestamp + } + ) + with errors::INVALID_ARGUMENT; + } + + /// Gets the current time in microseconds. + public fun now_microseconds(): u64 acquires CurrentTimeMicroseconds { + assert_operating(); + borrow_global(@CoreResources).microseconds + } + spec now_microseconds { + pragma opaque; + include AbortsIfNotOperating; + ensures result == spec_now_microseconds(); + } + spec fun spec_now_microseconds(): u64 { + global(@CoreResources).microseconds + } + + /// Gets the current time in seconds. + public fun now_seconds(): u64 acquires CurrentTimeMicroseconds { + now_microseconds() / MICRO_CONVERSION_FACTOR + } + spec now_seconds { + pragma opaque; + include AbortsIfNotOperating; + ensures result == spec_now_seconds(); + } + spec fun spec_now_seconds(): u64 { + spec_now_microseconds() / MICRO_CONVERSION_FACTOR + } + + /// Helper function to determine if Diem is in genesis state. + public fun is_genesis(): bool { + !exists(@CoreResources) + } + + /// Helper function to assert genesis state. + public fun assert_genesis() { + assert!(is_genesis(), errors::invalid_state(ENOT_GENESIS)); + } + spec assert_genesis { + pragma opaque = true; + include AbortsIfNotGenesis; + } + + /// Helper function to determine if Diem is operating. This is the same as `!is_genesis()` and is provided + /// for convenience. Testing `is_operating()` is more frequent than `is_genesis()`. + public fun is_operating(): bool { + exists(@CoreResources) + } + /// Helper schema to specify that a function aborts if not in genesis. + spec schema AbortsIfNotGenesis { + aborts_if !is_genesis() with errors::INVALID_STATE; + } + + /// Helper function to assert operating (!genesis) state. + public fun assert_operating() { + assert!(is_operating(), errors::invalid_state(ENOT_OPERATING)); + } + spec assert_operating { + pragma opaque = true; + include AbortsIfNotOperating; + } + + /// Helper schema to specify that a function aborts if not operating. + spec schema AbortsIfNotOperating { + aborts_if !is_operating() with errors::INVALID_STATE; + } + + // ==================== + // Module Specification + spec module {} // switch documentation context to module level + + spec module { + /// After genesis, `CurrentTimeMicroseconds` is published forever + invariant is_operating() ==> exists(@CoreResources); + + /// After genesis, time progresses monotonically. + invariant update + old(is_operating()) ==> old(spec_now_microseconds()) <= spec_now_microseconds(); + } + + spec module { + /// All functions which do not have an `aborts_if` specification in this module are implicitly declared + /// to never abort. + pragma aborts_if_is_strict; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/Signature.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/Signature.move new file mode 100644 index 000000000..e265918c3 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/Signature.move @@ -0,0 +1,24 @@ +/// Contains functions for [ed25519](https://en.wikipedia.org/wiki/EdDSA) digital signatures. +module CoreFramework::Signature { + + /// Return `true` if the bytes in `public_key` can be parsed as a valid Ed25519 public key. + /// Returns `false` if `public_key` is not 32 bytes OR is 32 bytes, but does not pass + /// points-on-curve or small subgroup checks. See the Rust `diem_crypto::Ed25519PublicKey` type + /// for more details. + /// Does not abort. + native public fun ed25519_validate_pubkey(public_key: vector): bool; + + /// Return true if the Ed25519 `signature` on `message` verifies against the Ed25519 public key + /// `public_key`. + /// Returns `false` if: + /// - `signature` is not 64 bytes + /// - `public_key` is not 32 bytes + /// - `public_key` does not pass points-on-curve or small subgroup checks, + /// - `signature` and `public_key` are valid, but the signature on `message` does not verify. + /// Does not abort. + native public fun ed25519_verify( + signature: vector, + public_key: vector, + message: vector + ): bool; +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/SystemAddresses.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/SystemAddresses.move new file mode 100644 index 000000000..f7b3b23c1 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/SystemAddresses.move @@ -0,0 +1,50 @@ +module CoreFramework::SystemAddresses { + use std::errors; + use std::signer; + + /// The address/account did not correspond to the core resource address + const ENOT_CORE_RESOURCE_ADDRESS: u64 = 0; + /// The operation can only be performed by the VM + const EVM: u64 = 1; + + public fun assert_core_resource(account: &signer) { + assert_core_resource_address(signer::address_of(account)) + } + spec assert_core_resource { + pragma opaque; + include AbortsIfNotCoreResource {addr: signer::address_of(account) }; + } + + public fun assert_core_resource_address(addr: address) { + assert!(is_core_resource_address(addr), errors::requires_address(ENOT_CORE_RESOURCE_ADDRESS)) + } + spec assert_core_resource_address { + pragma opaque; + include AbortsIfNotCoreResource; + } + + /// Specifies that a function aborts if the account does not have the Diem root address. + spec schema AbortsIfNotCoreResource { + addr: address; + aborts_if addr != @CoreResources with errors::REQUIRES_ADDRESS; + } + + public fun is_core_resource_address(addr: address): bool { + addr == @CoreResources + } + + /// Assert that the signer has the VM reserved address. + public fun assert_vm(account: &signer) { + assert!(signer::address_of(account) == @VMReserved, errors::requires_address(EVM)) + } + spec assert_vm { + pragma opaque; + include AbortsIfNotVM; + } + + /// Specifies that a function aborts if the account does not have the VM reserved address. + spec schema AbortsIfNotVM { + account: signer; + aborts_if signer::address_of(account) != @VMReserved with errors::REQUIRES_ADDRESS; + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemConsensusConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemConsensusConfig.move new file mode 100644 index 000000000..df8838e13 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemConsensusConfig.move @@ -0,0 +1,47 @@ +/// Maintains the consensus config for the Diem blockchain. The config is stored in a +/// DiemConfig, and may be updated by Diem root. +module CoreFramework::DiemConsensusConfig { + use std::capability::Cap; + use std::errors; + use std::vector; + use CoreFramework::DiemConfig; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + /// Error with chain marker + const ECHAIN_MARKER: u64 = 0; + /// Error with config + const ECONFIG: u64 = 1; + + /// Marker to be stored under @CoreResources during genesis + struct ConsensusConfigChainMarker has key {} + + struct DiemConsensusConfig has key { + config: vector, + } + + /// Publishes the DiemConsensusConfig config. + public fun initialize(account: &signer) { + DiemTimestamp::assert_genesis(); + SystemAddresses::assert_core_resource(account); + assert!( + !exists>(@CoreResources), + errors::already_published(ECHAIN_MARKER) + ); + + assert!( + !exists(@CoreResources), + errors::already_published(ECONFIG) + ); + move_to(account, ConsensusConfigChainMarker{}); + move_to(account, DiemConsensusConfig { config: vector::empty() }); + } + + /// Update the config. + public fun set(config: vector, _cap: &Cap) acquires DiemConsensusConfig { + assert!(exists>(@CoreResources), errors::not_published(ECHAIN_MARKER)); + let config_ref = &mut borrow_global_mut(@CoreResources).config; + *config_ref = config; + DiemConfig::reconfigure(); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemSystem.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemSystem.move new file mode 100644 index 000000000..ca944a3e3 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemSystem.move @@ -0,0 +1,297 @@ +/// Maintains information about the set of validators used during consensus. +/// Provides functions to add, remove, and update validators in the +/// validator set. +/// +/// > Note: When trying to understand this code, it's important to know that "config" +/// and "configuration" are used for several distinct concepts. +module CoreFramework::DiemSystem { + use std::capability::Cap; + use std::errors; + use std::option::{Self, Option}; + use std::signer; + use std::vector; + use CoreFramework::DiemConfig; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + use CoreFramework::ValidatorConfig; + + /// Marker to be stored under @CoreResources during genesis + struct ValidatorSetChainMarker has key {} + + /// Information about a Validator Owner. + struct ValidatorInfo has copy, drop, store { + /// The address (account) of the Validator Owner + addr: address, + /// The voting power of the Validator Owner (currently always 1). + consensus_voting_power: u64, + /// Configuration information about the Validator, such as the + /// Validator Operator, human name, and info such as consensus key + /// and network addresses. + config: ValidatorConfig::Config, + /// The time of last reconfiguration invoked by this validator + /// in microseconds + last_config_update_time: u64, + } + + /// The DiemSystem struct stores the validator set and crypto scheme in + /// DiemConfig. The DiemSystem struct is stored by DiemConfig, which publishes a + /// DiemConfig resource. + struct DiemSystem has key, copy, drop { + /// The current consensus crypto scheme. + scheme: u8, + /// The current validator set. + validators: vector, + } + + /// The `DiemSystem` resource was not in the required state + const ECONFIG: u64 = 0; + /// Tried to add a validator with an invalid state to the validator set + const EINVALID_PROSPECTIVE_VALIDATOR: u64 = 1; + /// Tried to add a validator to the validator set that was already in it + const EALREADY_A_VALIDATOR: u64 = 2; + /// An operation was attempted on an address not in the vaidator set + const ENOT_AN_ACTIVE_VALIDATOR: u64 = 3; + /// The validator operator is not the operator for the specified validator + const EINVALID_TRANSACTION_SENDER: u64 = 4; + /// An out of bounds index for the validator set was encountered + const EVALIDATOR_INDEX: u64 = 5; + /// Rate limited when trying to update config + const ECONFIG_UPDATE_RATE_LIMITED: u64 = 6; + /// Validator set already at maximum allowed size + const EMAX_VALIDATORS: u64 = 7; + /// Validator config update time overflows + const ECONFIG_UPDATE_TIME_OVERFLOWS: u64 = 8; + /// The `ValidatorSetChainMarker` resource was not in the required state + const ECHAIN_MARKER: u64 = 9; + + /// Number of microseconds in 5 minutes + const FIVE_MINUTES: u64 = 300000000; + + /// The maximum number of allowed validators in the validator set + const MAX_VALIDATORS: u64 = 256; + + /// The largest possible u64 value + const MAX_U64: u64 = 18446744073709551615; + + /////////////////////////////////////////////////////////////////////////// + // Setup methods + /////////////////////////////////////////////////////////////////////////// + + + /// Publishes the DiemSystem struct, which contains the current validator set. + /// Must be invoked by @CoreResources a single time in Genesis. + public fun initialize_validator_set( + account: &signer, + ) { + DiemTimestamp::assert_genesis(); + SystemAddresses::assert_core_resource(account); + + assert!(!exists>(@CoreResources), errors::already_published(ECHAIN_MARKER)); + assert!(!exists(@CoreResources), errors::already_published(ECONFIG)); + move_to(account, ValidatorSetChainMarker{}); + move_to( + account, + DiemSystem { + scheme: 0, + validators: vector::empty(), + }, + ); + } + + /// Copies a DiemSystem struct into the DiemSystem resource + /// Called by the add, remove, and update functions. + fun set_diem_system_config(value: DiemSystem) acquires DiemSystem { + DiemTimestamp::assert_operating(); + assert!( + exists(@CoreResources), + errors::not_published(ECONFIG) + ); + // Updates the DiemSystem and emits a reconfigure event. + let config_ref = borrow_global_mut(@CoreResources); + *config_ref = value; + DiemConfig::reconfigure(); + } + + /////////////////////////////////////////////////////////////////////////// + // Methods operating the Validator Set config callable by the diem root account + /////////////////////////////////////////////////////////////////////////// + + /// Adds a new validator to the validator set. + public fun add_validator( + validator_addr: address, + _cap: Cap + ) acquires DiemSystem { + DiemTimestamp::assert_operating(); + assert_chain_marker_is_published(); + + // A prospective validator must have a validator config resource + assert!( + ValidatorConfig::is_valid(validator_addr), + errors::invalid_argument(EINVALID_PROSPECTIVE_VALIDATOR) + ); + + // Bound the validator set size + assert!( + validator_set_size() < MAX_VALIDATORS, + errors::limit_exceeded(EMAX_VALIDATORS) + ); + + let diem_system_config = get_diem_system_config(); + + // Ensure that this address is not already a validator + assert!( + !is_validator_(validator_addr, &diem_system_config.validators), + errors::invalid_argument(EALREADY_A_VALIDATOR) + ); + + // it is guaranteed that the config is non-empty + let config = ValidatorConfig::get_config(validator_addr); + vector::push_back(&mut diem_system_config.validators, ValidatorInfo { + addr: validator_addr, + config, // copy the config over to ValidatorSet + consensus_voting_power: 1, + last_config_update_time: DiemTimestamp::now_microseconds(), + }); + + set_diem_system_config(diem_system_config); + } + + /// Removes a validator, aborts unless called by diem root account + public fun remove_validator( + validator_addr: address, + _cap: Cap + ) acquires DiemSystem { + DiemTimestamp::assert_operating(); + assert_chain_marker_is_published(); + + let diem_system_config = get_diem_system_config(); + // Ensure that this address is an active validator + let to_remove_index_vec = get_validator_index_(&diem_system_config.validators, validator_addr); + assert!(option::is_some(&to_remove_index_vec), errors::invalid_argument(ENOT_AN_ACTIVE_VALIDATOR)); + let to_remove_index = *option::borrow(&to_remove_index_vec); + // Remove corresponding ValidatorInfo from the validator set + _ = vector::swap_remove(&mut diem_system_config.validators, to_remove_index); + + set_diem_system_config(diem_system_config); + } + + /// Copy the information from ValidatorConfig into the validator set. + /// This function makes no changes to the size or the members of the set. + /// If the config in the ValidatorSet changes, it stores the new DiemSystem + /// and emits a reconfigurationevent. + public fun update_config_and_reconfigure( + validator_operator_account: &signer, + validator_addr: address, + ) acquires DiemSystem { + DiemTimestamp::assert_operating(); + assert!( + ValidatorConfig::get_operator(validator_addr) == signer::address_of(validator_operator_account), + errors::invalid_argument(EINVALID_TRANSACTION_SENDER) + ); + let diem_system_config = get_diem_system_config(); + let to_update_index_vec = get_validator_index_(&diem_system_config.validators, validator_addr); + assert!(option::is_some(&to_update_index_vec), errors::invalid_argument(ENOT_AN_ACTIVE_VALIDATOR)); + let to_update_index = *option::borrow(&to_update_index_vec); + let is_validator_info_updated = update_ith_validator_info_(&mut diem_system_config.validators, to_update_index); + if (is_validator_info_updated) { + let validator_info = vector::borrow_mut(&mut diem_system_config.validators, to_update_index); + assert!( + validator_info.last_config_update_time <= MAX_U64 - FIVE_MINUTES, + errors::limit_exceeded(ECONFIG_UPDATE_TIME_OVERFLOWS) + ); + assert!( + DiemTimestamp::now_microseconds() > validator_info.last_config_update_time + FIVE_MINUTES, + errors::limit_exceeded(ECONFIG_UPDATE_RATE_LIMITED) + ); + validator_info.last_config_update_time = DiemTimestamp::now_microseconds(); + set_diem_system_config(diem_system_config); + } + } + + /////////////////////////////////////////////////////////////////////////// + // Publicly callable APIs: getters + /////////////////////////////////////////////////////////////////////////// + + /// Get the DiemSystem configuration from DiemConfig + public fun get_diem_system_config(): DiemSystem acquires DiemSystem { + *borrow_global(@CoreResources) + } + + /// Return true if `addr` is in the current validator set + public fun is_validator(addr: address): bool acquires DiemSystem { + is_validator_(addr, &get_diem_system_config().validators) + } + + /// Returns validator config. Aborts if `addr` is not in the validator set. + public fun get_validator_config(addr: address): ValidatorConfig::Config acquires DiemSystem { + let diem_system_config = get_diem_system_config(); + let validator_index_vec = get_validator_index_(&diem_system_config.validators, addr); + assert!(option::is_some(&validator_index_vec), errors::invalid_argument(ENOT_AN_ACTIVE_VALIDATOR)); + *&(vector::borrow(&diem_system_config.validators, *option::borrow(&validator_index_vec))).config + } + + /// Return the size of the current validator set + public fun validator_set_size(): u64 acquires DiemSystem { + vector::length(&get_diem_system_config().validators) + } + + /// Get the `i`'th validator address in the validator set. + public fun get_ith_validator_address(i: u64): address acquires DiemSystem{ + assert!(i < validator_set_size(), errors::invalid_argument(EVALIDATOR_INDEX)); + vector::borrow(&get_diem_system_config().validators, i).addr + } + + /////////////////////////////////////////////////////////////////////////// + // Private functions + /////////////////////////////////////////////////////////////////////////// + + fun assert_chain_marker_is_published() { + assert!(exists>(@CoreResources), errors::not_published(ECHAIN_MARKER)); + } + + + /// Get the index of the validator by address in the `validators` vector + /// It has a loop, so there are spec blocks in the code to assert loop invariants. + fun get_validator_index_(validators: &vector, addr: address): Option { + let size = vector::length(validators); + let i = 0; + while (i < size) { + let validator_info_ref = vector::borrow(validators, i); + if (validator_info_ref.addr == addr) { + return option::some(i) + }; + i = i + 1; + }; + return option::none() + } + + /// Updates *i*th validator info, if nothing changed, return false. + /// This function never aborts. + fun update_ith_validator_info_(validators: &mut vector, i: u64): bool { + let size = vector::length(validators); + // This provably cannot happen, but left it here for safety. + if (i >= size) { + return false + }; + let validator_info = vector::borrow_mut(validators, i); + // "is_valid" below should always hold based on a global invariant later + // in the file (which proves if we comment out some other specifications), + // but it is left here for safety. + if (!ValidatorConfig::is_valid(validator_info.addr)) { + return false + }; + let new_validator_config = ValidatorConfig::get_config(validator_info.addr); + // check if information is the same + let config_ref = &mut validator_info.config; + if (config_ref == &new_validator_config) { + return false + }; + *config_ref = new_validator_config; + true + } + + /// Private function checks for membership of `addr` in validator set. + fun is_validator_(addr: address, validators_vec_ref: &vector): bool { + option::is_some(&get_validator_index_(validators_vec_ref, addr)) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemVMConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemVMConfig.move new file mode 100644 index 000000000..9f68efc1f --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemVMConfig.move @@ -0,0 +1,173 @@ +/// This module defines structs and methods to initialize VM configurations, +/// including different costs of running the VM. +module CoreFramework::DiemVMConfig { + use std::capability::Cap; + use std::errors; + use CoreFramework::DiemConfig; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + /// Error with chain marker + const ECHAIN_MARKER: u64 = 0; + /// Error with config + const ECONFIG: u64 = 1; + /// The provided gas constants were inconsistent. + const EGAS_CONSTANT_INCONSISTENCY: u64 = 2; + + /// Marker to be stored under @CoreResources during genesis + struct VMConfigChainMarker has key {} + + /// The struct to hold config data needed to operate the DiemVM. + struct DiemVMConfig has key { + /// Cost of running the VM. + gas_schedule: GasSchedule, + } + + /// The gas schedule keeps two separate schedules for the gas: + /// * The instruction_schedule: This holds the gas for each bytecode instruction. + /// * The native_schedule: This holds the gas for used (per-byte operated over) for each native + /// function. + /// A couple notes: + /// 1. In the case that an instruction is deleted from the bytecode, that part of the cost schedule + /// still needs to remain the same; once a slot in the table is taken by an instruction, that is its + /// slot for the rest of time (since that instruction could already exist in a module on-chain). + /// 2. The initialization of the module will publish the instruction table to the diem root account + /// address, and will preload the vector with the gas schedule for instructions. The VM will then + /// load this into memory at the startup of each block. + struct GasSchedule has copy, drop, store { + instruction_schedule: vector, + native_schedule: vector, + gas_constants: GasConstants, + } + + struct GasConstants has copy, drop, store { + /// The cost per-byte read from global storage. + global_memory_per_byte_cost: u64, + + /// The cost per-byte written to storage. + global_memory_per_byte_write_cost: u64, + + /// The flat minimum amount of gas required for any transaction. + /// Charged at the start of execution. + min_transaction_gas_units: u64, + + /// Any transaction over this size will be charged an additional amount per byte. + large_transaction_cutoff: u64, + + /// The units of gas to be charged per byte over the `large_transaction_cutoff` in addition to + /// `min_transaction_gas_units` for transactions whose size exceeds `large_transaction_cutoff`. + intrinsic_gas_per_byte: u64, + + /// ~5 microseconds should equal one unit of computational gas. We bound the maximum + /// computational time of any given transaction at roughly 20 seconds. We want this number and + /// `MAX_PRICE_PER_GAS_UNIT` to always satisfy the inequality that + /// MAXIMUM_NUMBER_OF_GAS_UNITS * MAX_PRICE_PER_GAS_UNIT < min(u64::MAX, GasUnits::MAX) + /// NB: The bound is set quite high since custom scripts aren't allowed except from predefined + /// and vetted senders. + maximum_number_of_gas_units: u64, + + /// The minimum gas price that a transaction can be submitted with. + min_price_per_gas_unit: u64, + + /// The maximum gas unit price that a transaction can be submitted with. + max_price_per_gas_unit: u64, + + max_transaction_size_in_bytes: u64, + gas_unit_scaling_factor: u64, + default_account_size: u64, + } + + /// Initialize the table under the diem root account + public fun initialize( + account: &signer, + instruction_schedule: vector, + native_schedule: vector, + ) { + DiemTimestamp::assert_genesis(); + + SystemAddresses::assert_core_resource(account); + + assert!( + !exists>(@CoreResources), + errors::already_published(ECHAIN_MARKER) + ); + + assert!( + !exists(@CoreResources), + errors::already_published(ECONFIG) + ); + + move_to(account, VMConfigChainMarker{}); + + let gas_constants = GasConstants { + global_memory_per_byte_cost: 4, + global_memory_per_byte_write_cost: 9, + min_transaction_gas_units: 600, + large_transaction_cutoff: 600, + intrinsic_gas_per_byte: 8, + maximum_number_of_gas_units: 4000000, + min_price_per_gas_unit: 0, + max_price_per_gas_unit: 10000, + max_transaction_size_in_bytes: 4096, + gas_unit_scaling_factor: 1000, + default_account_size: 800, + }; + + move_to( + account, + DiemVMConfig { + gas_schedule: GasSchedule { + instruction_schedule, + native_schedule, + gas_constants, + } + }, + ); + } + + public fun set_gas_constants( + global_memory_per_byte_cost: u64, + global_memory_per_byte_write_cost: u64, + min_transaction_gas_units: u64, + large_transaction_cutoff: u64, + intrinsic_gas_per_byte: u64, + maximum_number_of_gas_units: u64, + min_price_per_gas_unit: u64, + max_price_per_gas_unit: u64, + max_transaction_size_in_bytes: u64, + gas_unit_scaling_factor: u64, + default_account_size: u64, + _cap: &Cap + ) acquires DiemVMConfig { + DiemTimestamp::assert_operating(); + + assert!(exists>(@CoreResources), errors::not_published(ECHAIN_MARKER)); + + assert!( + min_price_per_gas_unit <= max_price_per_gas_unit, + errors::invalid_argument(EGAS_CONSTANT_INCONSISTENCY) + ); + assert!( + min_transaction_gas_units <= maximum_number_of_gas_units, + errors::invalid_argument(EGAS_CONSTANT_INCONSISTENCY) + ); + + assert!(exists(@CoreResources), errors::not_published(ECONFIG)); + + let gas_constants = &mut borrow_global_mut(@CoreResources).gas_schedule.gas_constants; + + gas_constants.global_memory_per_byte_cost = global_memory_per_byte_cost; + gas_constants.global_memory_per_byte_write_cost = global_memory_per_byte_write_cost; + gas_constants.min_transaction_gas_units = min_transaction_gas_units; + gas_constants.large_transaction_cutoff = large_transaction_cutoff; + gas_constants.intrinsic_gas_per_byte = intrinsic_gas_per_byte; + gas_constants.maximum_number_of_gas_units = maximum_number_of_gas_units; + gas_constants.min_price_per_gas_unit = min_price_per_gas_unit; + gas_constants.max_price_per_gas_unit = max_price_per_gas_unit; + gas_constants.max_transaction_size_in_bytes = max_transaction_size_in_bytes; + gas_constants.gas_unit_scaling_factor = gas_unit_scaling_factor; + gas_constants.default_account_size = default_account_size; + + DiemConfig::reconfigure(); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemVersion.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemVersion.move new file mode 100644 index 000000000..1429d806f --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/DiemVersion.move @@ -0,0 +1,65 @@ +/// Maintains the version number for the blockchain. +module CoreFramework::DiemVersion { + use std::capability::Cap; + use std::errors; + use CoreFramework::DiemConfig; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + /// Marker to be stored under 0x1 during genesis + struct VersionChainMarker has key {} + + struct DiemVersion has key, copy, drop, store { + major: u64, + } + + /// Error with chain marker + const ECHAIN_MARKER: u64 = 0; + /// Error with config + const ECONFIG: u64 = 1; + /// Tried to set an invalid major version for the VM. Major versions must be strictly increasing + const EINVALID_MAJOR_VERSION_NUMBER: u64 = 2; + + /// Publishes the Version config. + public fun initialize(account: &signer, initial_version: u64) { + DiemTimestamp::assert_genesis(); + + SystemAddresses::assert_core_resource(account); + + assert!( + !exists>(@CoreResources), + errors::already_published(ECHAIN_MARKER) + ); + + assert!( + !exists(@CoreResources), + errors::already_published(ECONFIG) + ); + + move_to( + account, + VersionChainMarker {}, + ); + move_to( + account, + DiemVersion { major: initial_version }, + ); + } + + /// Updates the major version to a larger version. + public fun set(major: u64, _cap: &Cap) acquires DiemVersion { + assert!(exists>(@CoreResources), errors::not_published(ECHAIN_MARKER)); + assert!(exists(@CoreResources), errors::not_published(ECONFIG)); + let old_major = *&borrow_global(@CoreResources).major; + + assert!( + old_major < major, + errors::invalid_argument(EINVALID_MAJOR_VERSION_NUMBER) + ); + + let config = borrow_global_mut(@CoreResources); + config.major = major; + + DiemConfig::reconfigure(); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ParallelExecutionConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ParallelExecutionConfig.move new file mode 100644 index 000000000..a7dac4846 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ParallelExecutionConfig.move @@ -0,0 +1,79 @@ +/// This module defines structs and methods to initialize VM configurations, +/// including different costs of running the VM. +module CoreFramework::ParallelExecutionConfig { + use std::capability::Cap; + use std::errors; + use std::option::{Self, Option}; + use CoreFramework::DiemConfig; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + /// Error with chain marker + const ECHAIN_MARKER: u64 = 0; + /// Error with config + const ECONFIG: u64 = 1; + + /// Marker to be stored under @CoreResources during genesis + struct ParallelExecutionConfigChainMarker has key {} + + /// The struct to hold the read/write set analysis result for the whole Diem Framework. + struct ParallelExecutionConfig has key { + /// Serialized analysis result for the Diem Framework. + /// If this payload is not None, DiemVM will use this config to execute transactions in parallel. + read_write_analysis_result: Option> + } + + /// Enable parallel execution functionality of DiemVM by setting the read_write_set analysis result. + public fun initialize_parallel_execution( + account: &signer, + ) { + DiemTimestamp::assert_genesis(); + SystemAddresses::assert_core_resource(account); + + assert!( + !exists>(@CoreResources), + errors::already_published(ECHAIN_MARKER) + ); + + assert!( + !exists(@CoreResources), + errors::already_published(ECONFIG) + ); + + move_to(account, ParallelExecutionConfigChainMarker{}); + + move_to( + account, + ParallelExecutionConfig { + read_write_analysis_result: option::none(), + }, + ); + } + + public fun enable_parallel_execution_with_config( + read_write_inference_result: vector, + _cap: &Cap + ) acquires ParallelExecutionConfig { + DiemTimestamp::assert_operating(); + assert!( + exists>(@CoreResources), + errors::not_published(ECHAIN_MARKER) + ); + let result_ref = &mut borrow_global_mut(@CoreResources).read_write_analysis_result; + *result_ref = option::some(read_write_inference_result); + DiemConfig::reconfigure(); + } + + public fun disable_parallel_execution( + _cap: &Cap + ) acquires ParallelExecutionConfig { + DiemTimestamp::assert_operating(); + assert!( + exists>(@CoreResources), + errors::not_published(ECHAIN_MARKER) + ); + let result_ref = &mut borrow_global_mut(@CoreResources).read_write_analysis_result; + *result_ref = option::none(); + DiemConfig::reconfigure(); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ValidatorConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ValidatorConfig.move new file mode 100644 index 000000000..e19ade0e0 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ValidatorConfig.move @@ -0,0 +1,200 @@ +/// The ValidatorConfig resource holds information about a validator. Information +/// is published and updated by Diem root in a `Self::ValidatorConfig` in preparation for +/// later inclusion (by functions in DiemConfig) in a `DiemConfig::DiemConfig` +/// struct (the `Self::ValidatorConfig` in a `DiemConfig::ValidatorInfo` which is a member +/// of the `DiemSystem::DiemSystem.validators` vector). +module CoreFramework::ValidatorConfig { + use std::capability::Cap; + use std::errors; + use std::option::{Self, Option}; + use std::signer; + use CoreFramework::DiemTimestamp; + use CoreFramework::ValidatorOperatorConfig; + use CoreFramework::Signature; + use CoreFramework::SystemAddresses; + + /// Marker to be stored under @CoreResources during genesis + struct ValidatorConfigChainMarker has key {} + + struct Config has copy, drop, store { + consensus_pubkey: vector, + validator_network_addresses: vector, + fullnode_network_addresses: vector, + } + + struct ValidatorConfig has key { + /// set and rotated by the operator_account + config: Option, + operator_account: Option
, + /// The human readable name of this entity. Immutable. + human_name: vector, + } + + // TODO(valerini): add events here + + /// The `ValidatorConfig` resource was not in the required state + const EVALIDATOR_CONFIG: u64 = 0; + /// The sender is not the operator for the specified validator + const EINVALID_TRANSACTION_SENDER: u64 = 1; + /// The provided consensus public key is malformed + const EINVALID_CONSENSUS_KEY: u64 = 2; + /// Tried to set an account without the correct operator role as a Validator Operator + const ENOT_A_VALIDATOR_OPERATOR: u64 = 3; + /// The `ValidatorSetChainMarker` resource was not in the required state + const ECHAIN_MARKER: u64 = 9; + + public fun initialize(account: &signer) { + DiemTimestamp::assert_genesis(); + SystemAddresses::assert_core_resource(account); + + assert!( + !exists>(@CoreResources), + errors::already_published(ECHAIN_MARKER) + ); + move_to(account, ValidatorConfigChainMarker{}); + } + + /////////////////////////////////////////////////////////////////////////// + // Validator setup methods + /////////////////////////////////////////////////////////////////////////// + + /// Publishes a mostly empty ValidatorConfig struct. Eventually, it + /// will have critical info such as keys, network addresses for validators, + /// and the address of the validator operator. + public fun publish( + validator_account: &signer, + human_name: vector, + _cap: Cap + ) { + DiemTimestamp::assert_operating(); + assert!( + exists>(@CoreResources), + errors::not_published(ECHAIN_MARKER) + ); + + assert!( + !exists(signer::address_of(validator_account)), + errors::already_published(EVALIDATOR_CONFIG) + ); + move_to(validator_account, ValidatorConfig { + config: option::none(), + operator_account: option::none(), + human_name, + }); + } + + /// Returns true if a ValidatorConfig resource exists under addr. + fun exists_config(addr: address): bool { + exists(addr) + } + + /////////////////////////////////////////////////////////////////////////// + // Rotation methods callable by ValidatorConfig owner + /////////////////////////////////////////////////////////////////////////// + + /// Sets a new operator account, preserving the old config. + /// Note: Access control. No one but the owner of the account may change .operator_account + public fun set_operator(validator_account: &signer, operator_addr: address) acquires ValidatorConfig { + assert!( + ValidatorOperatorConfig::has_validator_operator_config(operator_addr), + errors::invalid_argument(ENOT_A_VALIDATOR_OPERATOR) + ); + let sender = signer::address_of(validator_account); + assert!(exists_config(sender), errors::not_published(EVALIDATOR_CONFIG)); + (borrow_global_mut(sender)).operator_account = option::some(operator_addr); + } + + /// Removes an operator account, setting a corresponding field to Option::none. + /// The old config is preserved. + public fun remove_operator(validator_account: &signer) acquires ValidatorConfig { + let sender = signer::address_of(validator_account); + // Config field remains set + assert!(exists_config(sender), errors::not_published(EVALIDATOR_CONFIG)); + (borrow_global_mut(sender)).operator_account = option::none(); + } + + /////////////////////////////////////////////////////////////////////////// + // Rotation methods callable by ValidatorConfig.operator_account + /////////////////////////////////////////////////////////////////////////// + + /// Rotate the config in the validator_account. + /// Once the config is set, it can not go back to `Option::none` - this is crucial for validity + /// of the DiemSystem's code. + public fun set_config( + validator_operator_account: &signer, + validator_addr: address, + consensus_pubkey: vector, + validator_network_addresses: vector, + fullnode_network_addresses: vector, + ) acquires ValidatorConfig { + assert!( + signer::address_of(validator_operator_account) == get_operator(validator_addr), + errors::invalid_argument(EINVALID_TRANSACTION_SENDER) + ); + assert!( + Signature::ed25519_validate_pubkey(copy consensus_pubkey), + errors::invalid_argument(EINVALID_CONSENSUS_KEY) + ); + // TODO(valerini): verify the proof of posession for consensus_pubkey + assert!(exists_config(validator_addr), errors::not_published(EVALIDATOR_CONFIG)); + let t_ref = borrow_global_mut(validator_addr); + t_ref.config = option::some(Config { + consensus_pubkey, + validator_network_addresses, + fullnode_network_addresses, + }); + } + + /////////////////////////////////////////////////////////////////////////// + // Publicly callable APIs: getters + /////////////////////////////////////////////////////////////////////////// + + /// Returns true if all of the following is true: + /// 1) there is a ValidatorConfig resource under the address, and + /// 2) the config is set, and + /// we do not require the operator_account to be set to make sure + /// that if the validator account becomes valid, it stays valid, e.g. + /// all validators in the Validator Set are valid + public fun is_valid(addr: address): bool acquires ValidatorConfig { + exists(addr) && option::is_some(&borrow_global(addr).config) + } + + /// Get Config + /// Aborts if there is no ValidatorConfig resource or if its config is empty + public fun get_config(addr: address): Config acquires ValidatorConfig { + assert!(exists_config(addr), errors::not_published(EVALIDATOR_CONFIG)); + let config = &borrow_global(addr).config; + assert!(option::is_some(config), errors::invalid_argument(EVALIDATOR_CONFIG)); + *option::borrow(config) + } + + /// Get validator's account human name + /// Aborts if there is no ValidatorConfig resource + public fun get_human_name(addr: address): vector acquires ValidatorConfig { + assert!(exists(addr), errors::not_published(EVALIDATOR_CONFIG)); + let t_ref = borrow_global(addr); + *&t_ref.human_name + } + + /// Get operator's account + /// Aborts if there is no ValidatorConfig resource or + /// if the operator_account is unset + public fun get_operator(addr: address): address acquires ValidatorConfig { + assert!(exists(addr), errors::not_published(EVALIDATOR_CONFIG)); + let t_ref = borrow_global(addr); + assert!(option::is_some(&t_ref.operator_account), errors::invalid_argument(EVALIDATOR_CONFIG)); + *option::borrow(&t_ref.operator_account) + } + + /// Get consensus_pubkey from Config + /// Never aborts + public fun get_consensus_pubkey(config_ref: &Config): &vector { + &config_ref.consensus_pubkey + } + + /// Get validator's network address from Config + /// Never aborts + public fun get_validator_network_addresses(config_ref: &Config): &vector { + &config_ref.validator_network_addresses + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ValidatorOperatorConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ValidatorOperatorConfig.move new file mode 100644 index 000000000..e73f71579 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/core/sources/configs/ValidatorOperatorConfig.move @@ -0,0 +1,64 @@ +/// Stores the string name of a ValidatorOperator account. +module CoreFramework::ValidatorOperatorConfig { + use std::capability::Cap; + use std::errors; + use std::signer; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + /// Marker to be stored under @CoreResources during genesis + struct ValidatorOperatorConfigChainMarker has key {} + + struct ValidatorOperatorConfig has key { + /// The human readable name of this entity. Immutable. + human_name: vector, + } + + /// The `ValidatorOperatorConfig` was not in the required state + const EVALIDATOR_OPERATOR_CONFIG: u64 = 0; + /// The `ValidatorOperatorConfigChainMarker` resource was not in the required state + const ECHAIN_MARKER: u64 = 9; + + public fun initialize(account: &signer) { + DiemTimestamp::assert_genesis(); + SystemAddresses::assert_core_resource(account); + + assert!( + !exists>(@CoreResources), + errors::already_published(ECHAIN_MARKER) + ); + move_to(account, ValidatorOperatorConfigChainMarker{}); + } + + public fun publish( + validator_operator_account: &signer, + human_name: vector, + _cap: Cap + ) { + DiemTimestamp::assert_operating(); + assert!( + exists>(@CoreResources), + errors::not_published(ECHAIN_MARKER) + ); + + assert!( + !has_validator_operator_config(signer::address_of(validator_operator_account)), + errors::already_published(EVALIDATOR_OPERATOR_CONFIG) + ); + + move_to(validator_operator_account, ValidatorOperatorConfig { + human_name, + }); + } + + /// Get validator's account human name + /// Aborts if there is no ValidatorOperatorConfig resource + public fun get_human_name(validator_operator_addr: address): vector acquires ValidatorOperatorConfig { + assert!(has_validator_operator_config(validator_operator_addr), errors::not_published(EVALIDATOR_OPERATOR_CONFIG)); + *&borrow_global(validator_operator_addr).human_name + } + + public fun has_validator_operator_config(validator_operator_addr: address): bool { + exists(validator_operator_addr) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/Move.toml b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/Move.toml new file mode 100644 index 000000000..0341695ec --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/Move.toml @@ -0,0 +1,18 @@ +[package] +name = "DiemExperimental" +version = "1.5.0" + +[addresses] +std = "0x1" +DiemFramework = "0x1" +BARS = "0x06505CCD81E562B524D8F656ABD92A15" +ExperimentalFramework = "0x1" +DiemRoot = "0xA550C18" +TreasuryCompliance = "0xB1E55ED" +CurrencyInfo = "0xA550C18" +VMReserved = "0x0" + +[dependencies] +MoveStdlib = { local = "../../../../../move-stdlib" } + +DiemCoreFramework = { local = "../core" } diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/AccountCreationScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/AccountCreationScripts.move new file mode 100644 index 000000000..cbb10dc1d --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/AccountCreationScripts.move @@ -0,0 +1,139 @@ +module ExperimentalFramework::AccountCreationScripts { + use ExperimentalFramework::ExperimentalAccount; + + /// # Summary + /// Creates a Validator Operator account. This transaction can only be sent by the Diem + /// Root account. + /// + /// # Technical Description + /// Creates an account with a Validator Operator role at `new_account_address`, with authentication key + /// `auth_key_prefix` | `new_account_address`. It publishes a + /// `ValidatorOperatorConfig::ValidatorOperatorConfig` resource with the specified `human_name`. + /// This script does not assign the validator operator to any validator accounts but only creates the account. + /// + /// # Events + /// Successful execution will emit: + /// * A `ExperimentalAccount::CreateAccountEvent` with the `created` field being `new_account_address`, + /// and the `rold_id` field being `Roles::VALIDATOR_OPERATOR_ROLE_ID`. This is emitted on the + /// `ExperimentalAccount::AccountOperationsCapability` `creation_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | The signer of the sending account of this transaction. Must be the Diem Root signer. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `new_account_address` | `address` | Address of the to-be-created Validator account. | + /// | `auth_key_prefix` | `vector` | The authentication key prefix that will be used initially for the newly created account. | + /// | `human_name` | `vector` | ASCII-encoded human name for the validator. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::ALREADY_PUBLISHED` | `Roles::EROLE_ID` | The `new_account_address` address is already taken. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_account` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun create_validator_operator_account( + dr_account: signer, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector + ) { + ExperimentalAccount::create_validator_operator_account( + &dr_account, + new_account_address, + auth_key_prefix, + human_name, + ); + } + + /// # Summary + /// Creates a Validator account. This transaction can only be sent by the Diem + /// Root account. + /// + /// # Technical Description + /// Creates an account with a Validator role at `new_account_address`, with authentication key + /// `auth_key_prefix` | `new_account_address`. It publishes a + /// `ValidatorConfig::ValidatorConfig` resource with empty `config`, and + /// `operator_account` fields. The `human_name` field of the + /// `ValidatorConfig::ValidatorConfig` is set to the passed in `human_name`. + /// This script does not add the validator to the validator set or the system, + /// but only creates the account. + /// + /// # Events + /// Successful execution will emit: + /// * A `ExperimentalAccount::CreateAccountEvent` with the `created` field being `new_account_address`, + /// and the `rold_id` field being `Roles::VALIDATOR_ROLE_ID`. This is emitted on the + /// `ExperimentalAccount::AccountOperationsCapability` `creation_events` handle. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `dr_account` | `signer` | The signer of the sending account of this transaction. Must be the Diem Root signer. | + /// | `sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `new_account_address` | `address` | Address of the to-be-created Validator account. | + /// | `auth_key_prefix` | `vector` | The authentication key prefix that will be used initially for the newly created account. | + /// | `human_name` | `vector` | ASCII-encoded human name for the validator. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::NOT_PUBLISHED` | `SlidingNonce::ESLIDING_NONCE` | A `SlidingNonce` resource is not published under `dr_account`. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_OLD` | The `sliding_nonce` is too old and it's impossible to determine if it's duplicated or not. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_TOO_NEW` | The `sliding_nonce` is too far in the future. | + /// | `Errors::INVALID_ARGUMENT` | `SlidingNonce::ENONCE_ALREADY_RECORDED` | The `sliding_nonce` has been previously recorded. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::REQUIRES_ROLE` | `Roles::EDIEM_ROOT` | The sending account is not the Diem Root account. | + /// | `Errors::ALREADY_PUBLISHED` | `Roles::EROLE_ID` | The `new_account_address` address is already taken. | + /// + /// # Related Scripts + /// * `AccountCreationScripts::create_validator_operator_account` + /// * `ValidatorAdministrationScripts::add_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::register_validator_config` + /// * `ValidatorAdministrationScripts::remove_validator_and_reconfigure` + /// * `ValidatorAdministrationScripts::set_validator_operator` + /// * `ValidatorAdministrationScripts::set_validator_operator_with_nonce_admin` + /// * `ValidatorAdministrationScripts::set_validator_config_and_reconfigure` + + public entry fun create_validator_account( + dr_account: signer, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + ) { + ExperimentalAccount::create_validator_account( + &dr_account, + new_account_address, + auth_key_prefix, + human_name, + ); + } + + //////////////////////////////////////////////////////////////// + // Basic account creation script. + // No roles attached, no conditions checked. + //////////////////////////////////////////////////////////////// + public entry fun create_account( + _account: signer, + new_account_address: address, + auth_key_prefix: vector, + ) { + ExperimentalAccount::create_account( + new_account_address, + auth_key_prefix, + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/BARS.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/BARS.move new file mode 100644 index 000000000..b6459c7b7 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/BARS.move @@ -0,0 +1,107 @@ +module 0x1::BARSToken { + use std::option; + #[test_only] + use std::signer; + use 0x1::NFT; + use 0x1::NFTGallery; + #[test_only] + use std::guid; + + // Error codes + /// Function can only be called by the module owner + const ENOT_BARS_OWNER: u64 = 0; + + struct BARSToken has copy, store, drop { + artist_name: vector + } + + /// Call this function to set up relevant resources in order to + /// mint and receive tokens. + /// Note that this also gives BARS account a capability to mint BARS NFTs on behalf of the user. + /// (the NFTs of other types cannot be created by BARS account). + public entry fun register_bars_user(user: signer) { + register_user_internal(&user); + } + + /// Need this internal function for testing, since the script fun version + /// consumes a signer + fun register_user_internal(user: &signer) { + // publish TokenBalance resource + NFTGallery::publish_gallery(user); + + // publish TokenDataCollection resource + NFT::publish_token_data_collection(user); + + // The user gives BARS account capability to generate BARS NFTs on their behalf. + NFT::allow_creation_delegation(user); + } + + /// BARS account mints `amount` copies of BARS tokens to the artist's account. + public entry fun mint_bars( + bars_account: signer, + artist: address, + artist_name: vector, + content_uri: vector, + amount: u64 + ) { + mint_internal(&bars_account, artist, artist_name, content_uri, amount); + } + + /// Need this internal function for testing, since the script fun version + /// consumes a signer + fun mint_internal( + bars_account: &signer, + artist: address, + artist_name: vector, + content_uri: vector, + amount: u64 + ) { + let token = NFT::create_for( + artist, + create_bars_token(bars_account, artist_name), + content_uri, + amount, + option::none(), + ); + NFTGallery::add_to_gallery(artist, token); + } + + fun create_bars_token(address: &signer, artist_name: vector): BARSToken { + assert!(std::signer::address_of(address) == @BARS, ENOT_BARS_OWNER); + BARSToken { artist_name } + } + + #[test_only] + const EMINT_FAILED: u64 = 0; + #[test_only] + const ETRANSFER_FAILED: u64 = 1; + #[test_only] + const ArtistAddr: address = @0x42; + + #[test(admin=@DiemRoot, bars_account=@BARS, artist=@0x42, collector=@0x43)] + public entry fun test_bars(admin: signer, bars_account: signer, artist: signer, collector: signer) { + NFT::nft_initialize(admin); + + register_user_internal(&artist); + register_user_internal(&collector); + + let token_id = guid::create_id(ArtistAddr, 0); + mint_internal(&bars_account, signer::address_of(&artist), b"kanye", b"yeezy.com", 7); + + assert!(NFTGallery::has_token(ArtistAddr, &token_id), EMINT_FAILED); + assert!(NFTGallery::get_token_balance(ArtistAddr, &token_id) == 7, EMINT_FAILED); + assert!(NFTGallery::get_token_supply(ArtistAddr, &token_id) == 7, EMINT_FAILED); + + + // Transfer 6 units of the token from creator to user + NFTGallery::transfer_token_between_galleries( + artist, // from + signer::address_of(&collector), // to + 6, // amount + ArtistAddr, // token.id.addr + 0, // token.id.creation_num + ); + assert!(NFTGallery::get_token_balance(ArtistAddr, &token_id) == 1, ETRANSFER_FAILED); + assert!(NFTGallery::get_token_balance(@0x43, &token_id) == 6, ETRANSFER_FAILED); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/ExperimentalAccount.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/ExperimentalAccount.move new file mode 100644 index 000000000..8b426e93c --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/ExperimentalAccount.move @@ -0,0 +1,246 @@ +/// The `ExperimentalAccount` module manages experimental accounts. +/// It also defines the prolog and epilog that run before and after every +/// transaction in addition to the core prologue and epilogue. + +module ExperimentalFramework::ExperimentalAccount { + use std::event; + use std::errors; + use CoreFramework::Account; + use CoreFramework::DiemTimestamp; + use CoreFramework::SystemAddresses; + + use ExperimentalFramework::ExperimentalValidatorConfig; + use ExperimentalFramework::ExperimentalValidatorOperatorConfig; + + /// A resource that holds the event handle for all the past WriteSet transactions that have been committed on chain. + struct DiemWriteSetManager has key { + upgrade_events: event::EventHandle, + } + + /// Message for committed WriteSet transaction. + struct AdminTransactionEvent has drop, store { + // The block time when this WriteSet is committed. + committed_timestamp_secs: u64, + } + + const MAX_U64: u128 = 18446744073709551615; + + /// The `ExperimentalAccount` is not in the required state + const EACCOUNT: u64 = 0; + /// Tried to deposit a coin whose value was zero + const ECOIN_DEPOSIT_IS_ZERO: u64 = 2; + /// Tried to deposit funds that would have surpassed the account's limits + const EDEPOSIT_EXCEEDS_LIMITS: u64 = 3; + /// Tried to create a balance for an account whose role does not allow holding balances + const EROLE_CANT_STORE_BALANCE: u64 = 4; + /// The account does not hold a large enough balance in the specified currency + const EINSUFFICIENT_BALANCE: u64 = 5; + /// The withdrawal of funds would have exceeded the the account's limits + const EWITHDRAWAL_EXCEEDS_LIMITS: u64 = 6; + /// The `WithdrawCapability` for this account has already been extracted + const EWITHDRAW_CAPABILITY_ALREADY_EXTRACTED: u64 = 7; + /// The provided authentication had an invalid length + const EMALFORMED_AUTHENTICATION_KEY: u64 = 8; + /// The `KeyRotationCapability` for this account has already been extracted + const EKEY_ROTATION_CAPABILITY_ALREADY_EXTRACTED: u64 = 9; + /// An account cannot be created at the reserved VM address of 0x0 + const ECANNOT_CREATE_AT_VM_RESERVED: u64 = 10; + /// The `WithdrawCapability` for this account is not extracted + const EWITHDRAW_CAPABILITY_NOT_EXTRACTED: u64 = 11; + /// Tried to add a balance in a currency that this account already has + const EADD_EXISTING_CURRENCY: u64 = 15; + /// Attempted to send funds to an account that does not exist + const EPAYEE_DOES_NOT_EXIST: u64 = 17; + /// Attempted to send funds in a currency that the receiving account does not hold. + /// e.g., `Diem` to an account that exists, but does not have a `Balance` resource + const EPAYEE_CANT_ACCEPT_CURRENCY_TYPE: u64 = 18; + /// Tried to withdraw funds in a currency that the account does hold + const EPAYER_DOESNT_HOLD_CURRENCY: u64 = 19; + /// An invalid amount of gas units was provided for execution of the transaction + const EGAS: u64 = 20; + /// The `AccountOperationsCapability` was not in the required state + const EACCOUNT_OPERATIONS_CAPABILITY: u64 = 22; + /// The `DiemWriteSetManager` was not in the required state + const EWRITESET_MANAGER: u64 = 23; + /// An account cannot be created at the reserved core code address of 0x1 + const ECANNOT_CREATE_AT_CORE_CODE: u64 = 24; + + struct ExperimentalAccountMarker has drop {} + + fun create_core_account(account_address: address, auth_key_prefix: vector): (signer, vector) { + assert!( + account_address != @VMReserved, + errors::invalid_argument(ECANNOT_CREATE_AT_VM_RESERVED) + ); + assert!( + account_address != @CoreFramework, + errors::invalid_argument(ECANNOT_CREATE_AT_CORE_CODE) + ); + Account::create_account(account_address, auth_key_prefix, &ExperimentalAccountMarker{}) + } + + /// Initialize this module. This is only callable from genesis. + public fun initialize( + dr_account: &signer, + dummy_auth_key_prefix: vector, + ) { + DiemTimestamp::assert_genesis(); + // Operational constraint, not a privilege constraint. + SystemAddresses::assert_core_resource(dr_account); + Account::initialize( + dr_account, + @DiemFramework, + b"ExperimentalAccount", + b"script_prologue", + b"module_prologue", + b"writeset_prologue", + b"script_prologue", + b"epilogue", + b"writeset_epilogue", + false, + ); + + // TODO: For legacy reasons. Remove + create_diem_root_account( + copy dummy_auth_key_prefix, + ); + } + + /////////////////////////////////////////////////////////////////////////// + /// Basic account creation method: no roles attached, no conditions checked. + /////////////////////////////////////////////////////////////////////////// + + public fun create_account( + new_account_address: address, + auth_key_prefix: vector, + ) { + create_core_account(new_account_address, auth_key_prefix); + // No role attached + } + + public fun exists_at(addr: address): bool { + Account::exists_at(addr) + } + + /// Creates the diem root account (during genesis). Publishes the Diem root role, + /// Publishes a SlidingNonce resource, sets up event generator, publishes + /// AccountOperationsCapability, WriteSetManager, and finally makes the account. + fun create_diem_root_account( + auth_key_prefix: vector, + ) { + DiemTimestamp::assert_genesis(); + let (dr_account, _) = create_core_account(@CoreResources, auth_key_prefix); + SystemAddresses::assert_core_resource(&dr_account); + assert!( + !exists(@CoreResources), + errors::already_published(EWRITESET_MANAGER) + ); + move_to( + &dr_account, + DiemWriteSetManager { + upgrade_events: event::new_event_handle(&dr_account), + } + ); + } + + /// Create a Validator account + public fun create_validator_account( + dr_account: &signer, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + ) { + let (new_account, _) = create_core_account(new_account_address, auth_key_prefix); + ExperimentalValidatorConfig::publish(dr_account, &new_account, human_name); + } + + /// Create a Validator Operator account + public fun create_validator_operator_account( + dr_account: &signer, + new_account_address: address, + auth_key_prefix: vector, + human_name: vector, + ) { + let (new_account, _) = create_core_account(new_account_address, auth_key_prefix); + ExperimentalValidatorOperatorConfig::publish(dr_account, &new_account, human_name); + } + + /// Rotate the authentication key for the account under cap.account_address + public fun rotate_authentication_key( + account: &signer, + new_authentication_key: vector, + ) { + Account::rotate_authentication_key(account, new_authentication_key) + } + + /////////////////////////////////////////////////////////////////////////// + // Prologues and epilogues + /////////////////////////////////////////////////////////////////////////// + fun module_prologue( + sender: signer, + txn_sequence_number: u64, + txn_public_key: vector, + _txn_gas_price: u64, + _txn_max_gas_units: u64, + _txn_expiration_time: u64, + chain_id: u8, + ) { + Account::prologue(&sender, txn_sequence_number, txn_public_key, chain_id) + } + + fun script_prologue( + sender: signer, + txn_sequence_number: u64, + txn_public_key: vector, + _txn_gas_price: u64, + _txn_max_gas_units: u64, + _txn_expiration_time: u64, + chain_id: u8, + _script_hash: vector, + ) { + Account::prologue(&sender, txn_sequence_number, txn_public_key, chain_id) + } + + fun writeset_prologue( + sender: signer, + txn_sequence_number: u64, + txn_public_key: vector, + _txn_expiration_time: u64, + chain_id: u8, + ) { + Account::prologue(&sender, txn_sequence_number, txn_public_key, chain_id) + } + + // Might be able to combine this + fun multi_agent_script_prologue( + sender: signer, + txn_sequence_number: u64, + txn_sender_public_key: vector, + _secondary_signer_addresses: vector
, + _secondary_signer_public_key_hashes: vector>, + _txn_gas_price: u64, + _txn_max_gas_units: u64, + _txn_expiration_time: u64, + chain_id: u8, + ) { + Account::prologue(&sender, txn_sequence_number, txn_sender_public_key, chain_id) + } + + fun epilogue( + account: signer, + _txn_sequence_number: u64, + _txn_gas_price: u64, + _txn_max_gas_units: u64, + _gas_units_remaining: u64 + ) { + Account::epilogue(&account, &ExperimentalAccountMarker{}); + } + + fun writeset_epilogue( + dr_account: signer, + _txn_sequence_number: u64, + should_trigger_reconfiguration: bool, + ) { + Account::writeset_epilogue(&dr_account, should_trigger_reconfiguration, &ExperimentalAccountMarker{}); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/Genesis.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/Genesis.move new file mode 100644 index 000000000..f4ed409cc --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/Genesis.move @@ -0,0 +1,190 @@ +module ExperimentalFramework::Genesis { + use std::signer; + use std::event; + use std::vector; + use CoreFramework::CoreGenesis; + use ExperimentalFramework::ExperimentalAccount; + + // Config imports + use CoreFramework::ValidatorConfig; + use CoreFramework::ValidatorOperatorConfig; + use ExperimentalFramework::ExperimentalConsensusConfig; + use ExperimentalFramework::ExperimentalParallelExecutionConfig; + use ExperimentalFramework::ExperimentalValidatorConfig; + use ExperimentalFramework::ExperimentalValidatorOperatorConfig; + use ExperimentalFramework::ExperimentalValidatorSet; + use ExperimentalFramework::ExperimentalVersion; + use ExperimentalFramework::ExperimentalVMConfig; + + // This function needs the same signature as the DPN genesis + fun initialize( + dr_account: signer, + _tc_account: signer, + dr_auth_key: vector, + _tc_auth_key: vector, + _initial_script_allow_list: vector>, + _is_open_module: bool, + instruction_schedule: vector, + native_schedule: vector, + chain_id: u8, + initial_diem_version: u64, + consensus_config: vector, + ) { + initialize_internal( + &dr_account, + dr_auth_key, + instruction_schedule, + native_schedule, + chain_id, + initial_diem_version, + consensus_config, + ) + } + + fun initialize_internal( + dr_account: &signer, + dr_auth_key: vector, + instruction_schedule: vector, + native_schedule: vector, + chain_id: u8, + initial_diem_version: u64, + consensus_config: vector, + ) { + ExperimentalAccount::initialize(dr_account, x"00000000000000000000000000000000"); + + // Pad the event counter for the Diem Root account to match DPN. This + // _MUST_ match the new epoch event counter otherwise all manner of + // things start to break. + event::destroy_handle(event::new_event_handle(dr_account)); + event::destroy_handle(event::new_event_handle(dr_account)); + event::destroy_handle(event::new_event_handle(dr_account)); + + // Consensus config setup + ExperimentalConsensusConfig::initialize(dr_account); + // Parallel execution config setup + ExperimentalParallelExecutionConfig::initialize_parallel_execution(dr_account); + ExperimentalValidatorSet::initialize_validator_set(dr_account); + ExperimentalVersion::initialize(dr_account, initial_diem_version); + + // Rotate auth keys for DiemRoot account to the given + // values + ExperimentalAccount::rotate_authentication_key(dr_account, dr_auth_key); + ExperimentalVMConfig::initialize( + dr_account, + instruction_schedule, + native_schedule, + ); + + ExperimentalConsensusConfig::set(dr_account, consensus_config); + + ExperimentalValidatorConfig::initialize(dr_account); + ExperimentalValidatorOperatorConfig::initialize(dr_account); + + // this needs to be called at the very end + CoreGenesis::init(dr_account, chain_id); + } + + /// Sets up the initial validator set for the Diem network. + /// The validator "owner" accounts, their UTF-8 names, and their authentication + /// keys are encoded in the `owners`, `owner_names`, and `owner_auth_key` vectors. + /// Each validator signs consensus messages with the private key corresponding to the Ed25519 + /// public key in `consensus_pubkeys`. + /// Each validator owner has its operation delegated to an "operator" (which may be + /// the owner). The operators, their names, and their authentication keys are encoded + /// in the `operators`, `operator_names`, and `operator_auth_keys` vectors. + /// Finally, each validator must specify the network address + /// (see diem/types/src/network_address/mod.rs) for itself and its full nodes. + fun create_initialize_owners_operators( + dr_account: signer, + owners: vector, + owner_names: vector>, + owner_auth_keys: vector>, + consensus_pubkeys: vector>, + operators: vector, + operator_names: vector>, + operator_auth_keys: vector>, + validator_network_addresses: vector>, + full_node_network_addresses: vector>, + ) { + let num_owners = vector::length(&owners); + let num_owner_names = vector::length(&owner_names); + assert!(num_owners == num_owner_names, 0); + let num_owner_keys = vector::length(&owner_auth_keys); + assert!(num_owner_names == num_owner_keys, 0); + let num_operators = vector::length(&operators); + assert!(num_owner_keys == num_operators, 0); + let num_operator_names = vector::length(&operator_names); + assert!(num_operators == num_operator_names, 0); + let num_operator_keys = vector::length(&operator_auth_keys); + assert!(num_operator_names == num_operator_keys, 0); + let num_validator_network_addresses = vector::length(&validator_network_addresses); + assert!(num_operator_keys == num_validator_network_addresses, 0); + let num_full_node_network_addresses = vector::length(&full_node_network_addresses); + assert!(num_validator_network_addresses == num_full_node_network_addresses, 0); + + let i = 0; + let dummy_auth_key_prefix = x"00000000000000000000000000000000"; + while (i < num_owners) { + let owner = vector::borrow(&owners, i); + let owner_address = signer::address_of(owner); + let owner_name = *vector::borrow(&owner_names, i); + // create each validator account and rotate its auth key to the correct value + ExperimentalAccount::create_validator_account( + &dr_account, owner_address, copy dummy_auth_key_prefix, owner_name + ); + + let owner_auth_key = *vector::borrow(&owner_auth_keys, i); + ExperimentalAccount::rotate_authentication_key(owner, owner_auth_key); + + let operator = vector::borrow(&operators, i); + let operator_address = signer::address_of(operator); + let operator_name = *vector::borrow(&operator_names, i); + // create the operator account + rotate its auth key if it does not already exist + if (!ExperimentalAccount::exists_at(operator_address)) { + ExperimentalAccount::create_validator_operator_account( + &dr_account, operator_address, copy dummy_auth_key_prefix, copy operator_name + ); + let operator_auth_key = *vector::borrow(&operator_auth_keys, i); + ExperimentalAccount::rotate_authentication_key(operator, operator_auth_key); + }; + // assign the operator to its validator + assert!(ValidatorOperatorConfig::get_human_name(operator_address) == operator_name, 0); + ValidatorConfig::set_operator(owner, operator_address); + + // use the operator account set up the validator config + let validator_network_address = *vector::borrow(&validator_network_addresses, i); + let full_node_network_address = *vector::borrow(&full_node_network_addresses, i); + let consensus_pubkey = *vector::borrow(&consensus_pubkeys, i); + ValidatorConfig::set_config( + operator, + owner_address, + consensus_pubkey, + validator_network_address, + full_node_network_address + ); + + // finally, add this validator to the validator set + ExperimentalValidatorSet::add_validator(&dr_account, owner_address); + + i = i + 1; + } + } + + #[test_only] + public fun setup(dr_account: &signer) { + initialize_internal( + dr_account, + x"0000000000000000000000000000000000000000000000000000000000000000", + x"", // instruction_schedule not needed for unit tests + x"", // native schedule not needed for unit tests + 4u8, // TESTING chain ID + 0, + x"" + ) + } + + #[test(account = @CoreResources)] + fun test_setup(account: signer) { + setup(&account); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/MultiToken.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/MultiToken.move new file mode 100644 index 000000000..494f2105c --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/MultiToken.move @@ -0,0 +1,269 @@ +module ExperimentalFramework::MultiToken { + use std::errors; + use std::event; + use std::guid; + use std::option::{Self, Option}; + use std::signer; + use std::vector; + + /// Struct representing data of a specific token with token_id, + /// stored under the creator's address inside TokenInfoCollection. + /// For each token_id, there is only one MultiTokenData. + struct TokenData has key, store { + metadata: Option, + /// Identifier for the token. + token_id: guid::GUID, + /// Pointer to where the content and metadata is stored. + content_uri: vector, + supply: u64, + } + + /// A hot potato wrapper for the token's metadata. Since this wrapper has no `key` or `store` + /// ability, it can't be stored in global storage. This wrapper can be safely passed outside + /// of this module because we know it will have to come back to this module, where + /// it will be unpacked. + struct TokenDataWrapper { + origin: address, + index: u64, + metadata: TokenType, + } + + /// Struct representing a semi-fungible or non-fungible token (depending on the supply). + /// There can be multiple tokens with the same id (unless supply is 1). Each token's + /// corresponding token metadata is stored inside a MultiTokenData inside TokenDataCollection + /// under the creator's address. + struct Token has key, store { + id: guid::ID, + balance: u64, + } + + struct MintEvent has copy, drop, store { + id: guid::ID, + creator: address, + content_uri: vector, + amount: u64, + } + + struct Admin has key { + mint_events: event::EventHandle, + } + + struct TokenDataCollection has key { + tokens: vector>, + } + + spec fun get_tokens(addr: address): vector>{ + global>(addr).tokens + } + + spec fun is_in_tokens(tokens: vector>, token_id: guid::ID): bool { + exists token in tokens: token.token_id.id == token_id + } + + spec fun find_token_index_by_id(tokens: vector>, id: guid::ID): u64 { + choose min i in range(tokens) where tokens[i].token_id.id == id + } + + const ADMIN: address = @0xa550c18; + const MAX_U64: u64 = 18446744073709551615u64; + // Error codes + /// Function can only be called by the admin address + const ENOT_ADMIN: u64 = 0; + const EWRONG_TOKEN_ID: u64 = 1; + const ETOKEN_BALANCE_OVERFLOWS: u64 = 2; + const EAMOUNT_EXCEEDS_TOKEN_BALANCE: u64 = 3; + const ETOKEN_EXTRACTED: u64 = 4; + const EINDEX_EXCEEDS_LENGTH: u64 = 5; + const ETOKEN_PRESENT: u64 = 6; + + /// Returns the id of given token + public fun id(token: &Token): guid::ID { + *&token.id + } + + /// Returns the balance of given token + public fun balance(token: &Token): u64 { + token.balance + } + + public fun metadata(wrapper: &TokenDataWrapper): &TokenType { + &wrapper.metadata + } + + /// Returns the supply of tokens with `id` on the chain. + public fun supply(id: &guid::ID): u64 acquires TokenDataCollection { + let owner_addr = guid::id_creator_address(id); + let tokens = &mut borrow_global_mut>(owner_addr).tokens; + let index_opt = index_of_token(tokens, id); + assert!(option::is_some(&index_opt), errors::invalid_argument(EWRONG_TOKEN_ID)); + let index = option::extract(&mut index_opt); + vector::borrow(tokens, index).supply + } + + spec supply { + let addr = guid::id_creator_address(id); + let token_collection = get_tokens(addr); + let min_token_idx = find_token_index_by_id(token_collection,id); + aborts_if !exists>(addr); + aborts_if !is_in_tokens(token_collection, id); + ensures result == token_collection[min_token_idx].supply; + } + + /// Extract the MultiToken data of the given token into a hot potato wrapper. + public fun extract_token(nft: &Token): TokenDataWrapper acquires TokenDataCollection { + let owner_addr = guid::id_creator_address(&nft.id); + let tokens = &mut borrow_global_mut>(owner_addr).tokens; + let index_opt = index_of_token(tokens, &nft.id); + assert!(option::is_some(&index_opt), errors::invalid_argument(EWRONG_TOKEN_ID)); + let index = option::extract(&mut index_opt); + let item_opt = &mut vector::borrow_mut(tokens, index).metadata; + assert!(option::is_some(item_opt), errors::invalid_state(ETOKEN_EXTRACTED)); + TokenDataWrapper { origin: owner_addr, index, metadata: option::extract(item_opt) } + } + + spec extract_token { + let addr = guid::id_creator_address(nft.id); + let token_collection = get_tokens(addr); + let id = nft.id; + let min_token_idx = find_token_index_by_id(token_collection, id); + aborts_if !exists>(addr); + aborts_if token_collection[min_token_idx].metadata == option::spec_none(); + aborts_if !is_in_tokens(token_collection, id); + ensures result == TokenDataWrapper { origin: addr, index: min_token_idx, + metadata: option::borrow(token_collection[min_token_idx].metadata)}; + ensures get_tokens(addr)[min_token_idx].metadata == option::spec_none(); + } + + /// Restore the token in the wrapper back into global storage under original address. + public fun restore_token(wrapper: TokenDataWrapper) acquires TokenDataCollection { + let TokenDataWrapper { origin, index, metadata } = wrapper; + let tokens = &mut borrow_global_mut>(origin).tokens; + assert!(vector::length(tokens) > index, EINDEX_EXCEEDS_LENGTH); + let item_opt = &mut vector::borrow_mut(tokens, index).metadata; + assert!(option::is_none(item_opt), ETOKEN_PRESENT); + option::fill(item_opt, metadata); + } + + spec restore_token { + let addr = wrapper.origin; + let token_collection = get_tokens(addr); + let item_opt = token_collection[wrapper.index].metadata; + aborts_if !exists>(addr); + aborts_if len(token_collection) <= wrapper.index; + aborts_if item_opt != option::spec_none(); + ensures get_tokens(addr)[wrapper.index].metadata == option::spec_some(wrapper.metadata); + } + + /// Finds the index of token with the given id in the gallery. + fun index_of_token(gallery: &vector>, id: &guid::ID): Option { + let i = 0; + let len = vector::length(gallery); + while ({spec { + invariant i >= 0; + invariant i <= len(gallery); + invariant forall k in 0..i: gallery[k].token_id.id != id; + };(i < len)}) { + if (guid::eq_id(&vector::borrow(gallery, i).token_id, id)) { + return option::some(i) + }; + i = i + 1; + }; + option::none() + } + + spec index_of_token{ + let min_token_idx = find_token_index_by_id(gallery, id); + let post res_id = option::borrow(result); + ensures is_in_tokens(gallery, id) <==> (option::is_some(result) && res_id == min_token_idx); + ensures result == option::spec_none() <==> !is_in_tokens(gallery, id); + } + + /// Join two multi tokens and return a multi token with the combined value of the two. + public fun join(token: &mut Token, other: Token) { + let Token { id, balance } = other; + assert!(*&token.id == id, EWRONG_TOKEN_ID); + assert!(MAX_U64 - token.balance >= balance, ETOKEN_BALANCE_OVERFLOWS); + token.balance = token.balance + balance + } + + spec join{ + aborts_if token.id != other.id with EWRONG_TOKEN_ID; + aborts_if MAX_U64 - token.balance < other.balance with ETOKEN_BALANCE_OVERFLOWS; + ensures token.balance == old(token).balance + other.balance; + } + + /// Split the token into two tokens, one with balance `amount` and the other one with balance + public fun split(token: Token, amount: u64): (Token, Token) { + assert!(token.balance >= amount, EAMOUNT_EXCEEDS_TOKEN_BALANCE); + token.balance = token.balance - amount; + let id = *&token.id; + (token, + Token { + id, + balance: amount + } ) + } + + spec split { + aborts_if token.balance < amount with EAMOUNT_EXCEEDS_TOKEN_BALANCE; + ensures result_1.balance == token.balance - amount; + ensures result_2.balance == amount; + ensures result_1.id == result_2.id; + } + + /// Initialize this module, to be called in genesis. + public fun initialize_multi_token(account: signer) { + assert!(signer::address_of(&account) == ADMIN, ENOT_ADMIN); + move_to(&account, Admin { + mint_events: event::new_event_handle(&account), + }) + } + + spec initialize_multi_token{ + let addr = signer::address_of(account); + aborts_if addr != ADMIN; + aborts_if exists(addr); + ensures exists(addr); + } + + /// Create a` TokenData` that wraps `metadata` and with balance of `amount` + public fun create( + account: &signer, metadata: TokenType, content_uri: vector, amount: u64 + ): Token acquires Admin, TokenDataCollection { + let guid = guid::create(account); + event::emit_event( + &mut borrow_global_mut(ADMIN).mint_events, + MintEvent { + id: guid::id(&guid), + creator: signer::address_of(account), + content_uri: copy content_uri, + amount, + } + ); + let id = guid::id(&guid); + if (!exists>(signer::address_of(account))) { + move_to(account, TokenDataCollection { tokens: vector::empty>() }); + }; + let token_data_collection = &mut borrow_global_mut>(signer::address_of(account)).tokens; + vector::push_back( + token_data_collection, + TokenData { metadata: option::some(metadata), token_id: guid, content_uri, supply: amount } + ); + Token { id, balance: amount } + } + + spec create { + let addr = signer::address_of(account); + let post post_tokens = get_tokens(addr); + + aborts_if !exists(ADMIN); + aborts_if exists(addr) && global(addr).counter + 1 > MAX_U64; + + ensures result.balance == amount; + ensures guid::id_creator_address(result.id) == addr; + ensures exists>(addr); + ensures post_tokens[len(post_tokens) - 1] == + TokenData {metadata: option::spec_some(metadata), token_id: guid::GUID {id: result.id}, content_uri, supply:amount}; + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/MultiTokenBalance.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/MultiTokenBalance.move new file mode 100644 index 000000000..f87809d8a --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/MultiTokenBalance.move @@ -0,0 +1,239 @@ +module ExperimentalFramework::MultiTokenBalance { + use std::errors; + use std::guid; + use ExperimentalFramework::MultiToken::{Self, Token}; + use std::option::{Self, Option}; + use std::signer; + use std::vector; + + /// Balance holding tokens of `TokenType` as well as information of approved operators. + struct TokenBalance has key { + /// Gallery full of multi tokens owned by this balance + gallery: vector> + } + + spec TokenBalance { + invariant forall i1 in range(gallery), i2 in range(gallery) where gallery[i1].id == gallery[i2].id: + i1 == i2; + } + + spec fun get_token_balance_gallery(addr: address): vector>{ + global>(addr).gallery + } + + spec fun is_in_gallery(gallery: vector>, token_id: guid::ID): bool { + exists i in range(gallery): gallery[i].id == token_id + } + + spec fun find_token_index_by_id(gallery: vector>, id: guid::ID): u64 { + choose i in range(gallery) where gallery[i].id == id + } + + const MAX_U64: u128 = 18446744073709551615u128; + // Error codes + const EID_NOT_FOUND: u64 = 0; + const EBALANCE_NOT_PUBLISHED: u64 = 1; + const EBALANCE_ALREADY_PUBLISHED: u64 = 2; + const EINVALID_AMOUNT_OF_TRANSFER: u64 = 3; + const EALREADY_IS_OPERATOR: u64 = 4; + const ENOT_OPERATOR: u64 = 5; + const EINVALID_APPROVAL_TARGET: u64 = 6; + + + + /// Add a token to the owner's gallery. If there is already a token of the same id in the + /// gallery, we combine it with the new one and make a token of greater value. + public fun add_to_gallery(owner: address, token: Token) + acquires TokenBalance { + assert!(exists>(owner), EBALANCE_NOT_PUBLISHED); + let id = MultiToken::id(&token); + if (has_token(owner, &id)) { + // If `owner` already has a token with the same id, remove it from the gallery + // and join it with the new token. + let original_token = remove_from_gallery(owner, &id); + MultiToken::join(&mut token, original_token); + }; + let gallery = &mut borrow_global_mut>(owner).gallery; + vector::push_back(gallery, token); + } + + + + spec add_to_gallery { + let gallery = get_token_balance_gallery(owner); + let token_bal = token.balance; + let min_token_idx = find_token_index_by_id(gallery, token.id); + let balance = gallery[min_token_idx].balance; + let post post_gallery = get_token_balance_gallery(owner); + + aborts_if !exists>(owner); + aborts_if is_in_gallery(gallery, token.id) && MAX_U64 - token.balance < balance; + + ensures is_in_gallery(gallery, token.id) ==> len(gallery) == len(post_gallery); + ensures !is_in_gallery(gallery, token.id) ==> len(gallery) + 1 == len(post_gallery); + + ensures is_in_gallery(gallery, token.id) ==> post_gallery[len(gallery) - 1].balance == + token_bal + gallery[min_token_idx].balance; + ensures post_gallery[len(post_gallery) - 1].id == token.id; + } + + /// Remove a token of certain id from the owner's gallery and return it. + fun remove_from_gallery(owner: address, id: &guid::ID): Token + acquires TokenBalance { + assert!(exists>(owner), EBALANCE_NOT_PUBLISHED); + let gallery = &mut borrow_global_mut>(owner).gallery; + let index_opt = index_of_token(gallery, id); + assert!(option::is_some(&index_opt), errors::limit_exceeded(EID_NOT_FOUND)); + vector::remove(gallery, option::extract(&mut index_opt)) + } + + spec remove_from_gallery { + let gallery = get_token_balance_gallery(owner); + aborts_if !exists>(owner); + aborts_if !is_in_gallery(gallery, id); + ensures !is_in_gallery(get_token_balance_gallery(owner), id); + } + + /// Finds the index of token with the given id in the gallery. + fun index_of_token(gallery: &vector>, id: &guid::ID): Option { + let i = 0; + let len = vector::length(gallery); + while ({spec { + invariant i >= 0; + invariant i <= len(gallery); + invariant forall k in 0..i: gallery[k].id != id; + };(i < len)}) { + if (MultiToken::id(vector::borrow(gallery, i)) == *id) { + return option::some(i) + }; + i = i + 1; + }; + option::none() + } + + spec index_of_token{ + let min_token_idx = choose min i in range(gallery) where gallery[i].id == id; + let post res_id = option::borrow(result); + ensures is_in_gallery(gallery, id) <==> (option::is_some(result) && res_id == min_token_idx); + ensures result == option::spec_none() <==> !is_in_gallery(gallery, id); + } + + /// Returns whether the owner has a token with given id. + public fun has_token(owner: address, token_id: &guid::ID): bool acquires TokenBalance { + option::is_some(&index_of_token(&borrow_global>(owner).gallery, token_id)) + } + + spec has_token { + let gallery = global>(owner).gallery; + ensures result <==> is_in_gallery(gallery, token_id); + } + + public fun get_token_balance(owner: address, token_id: &guid::ID + ): u64 acquires TokenBalance { + let gallery = &borrow_global>(owner).gallery; + let index_opt = index_of_token(gallery, token_id); + + if (option::is_none(&index_opt)) { + 0 + } else { + let index = option::extract(&mut index_opt); + MultiToken::balance(vector::borrow(gallery, index)) + } + } + + spec get_token_balance { + let gallery = get_token_balance_gallery(owner); + let min_token_idx = find_token_index_by_id(gallery, token_id); + ensures !is_in_gallery(gallery, token_id) ==> result == 0; + ensures is_in_gallery(gallery, token_id) ==> result == gallery[min_token_idx].balance; + } + + /// Transfer `amount` of token with id `GUID::id(creator, creation_num)` from `owner`'s + /// balance to `to`'s balance. This operation has to be done by either the owner or an + /// approved operator of the owner. + public entry fun transfer_multi_token_between_galleries( + account: signer, + to: address, + amount: u64, + creator: address, + creation_num: u64 + ) acquires TokenBalance { + let owner = signer::address_of(&account); + + assert!(amount > 0, EINVALID_AMOUNT_OF_TRANSFER); + + // Remove NFT from `owner`'s gallery + let id = guid::create_id(creator, creation_num); + let token = remove_from_gallery(owner, &id); + + assert!(amount <= MultiToken::balance(&token), EINVALID_AMOUNT_OF_TRANSFER); + + if (amount == MultiToken::balance(&token)) { + // Owner does not have any token left, so add token to `to`'s gallery. + add_to_gallery(to, token); + } else { + // Split owner's token into two + let (owner_token, to_token) = MultiToken::split(token, amount); + + // Add tokens to owner's gallery. + add_to_gallery(owner, owner_token); + + // Add tokens to `to`'s gallery + add_to_gallery(to, to_token); + }; + + // TODO: add event emission + } + + spec transfer_multi_token_between_galleries { + let owner = signer::address_of(account); + let gallery_owner = get_token_balance_gallery(owner); + let gallery_to = get_token_balance_gallery(to); + let post post_gallery_owner = get_token_balance_gallery(owner); + let post post_gallery_to = get_token_balance_gallery(to); + + let id = guid::create_id(creator, creation_num); + + let min_token_idx = find_token_index_by_id(gallery_owner, id); + let min_token_idx_to = find_token_index_by_id(gallery_to, id); + + aborts_if amount <= 0; + aborts_if !exists>(owner); + aborts_if !exists>(to); + aborts_if !is_in_gallery(gallery_owner, id); + aborts_if amount > gallery_owner[min_token_idx].balance; + aborts_if owner != to && is_in_gallery(gallery_to, id) && MAX_U64 - amount < gallery_to[min_token_idx_to].balance; + + ensures (gallery_owner[min_token_idx].balance == amount && to != owner) ==> + !is_in_gallery(post_gallery_owner, id); + + ensures gallery_owner[min_token_idx].balance > amount ==> + post_gallery_owner[len(post_gallery_owner) - 1].id == id; + ensures post_gallery_to[len(post_gallery_to) - 1].id == id; + + ensures (gallery_owner[min_token_idx].balance > amount && to != owner) ==> + post_gallery_owner[len(post_gallery_owner) - 1].balance == + gallery_owner[min_token_idx].balance - amount; + + ensures (to != owner && !is_in_gallery(gallery_to, id) )==> + post_gallery_to[len(post_gallery_to) - 1].balance == amount; + ensures (to != owner && is_in_gallery(gallery_to, id) )==> + post_gallery_to[len(post_gallery_to) - 1].balance == + gallery_to[min_token_idx_to].balance + amount; + + ensures to == owner ==> post_gallery_owner[len(post_gallery_owner) - 1].balance == + gallery_owner[min_token_idx].balance; + + } + + public fun publish_balance(account: &signer) { + assert!(!exists>(signer::address_of(account)), EBALANCE_ALREADY_PUBLISHED); + move_to(account, TokenBalance { gallery: vector::empty() }); + } + + spec publish_balance { + let addr = signer::address_of(account); + aborts_if exists>(addr); + ensures exists>(addr); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/NFT.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/NFT.move new file mode 100644 index 000000000..deae29c70 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/NFT.move @@ -0,0 +1,300 @@ +address 0x1 { + module NFT { + use std::event; + use std::guid; + use std::option::{Self, Option}; + use std::signer; + use std::vector; + + /// Struct representing a semi-fungible or non-fungible token (depending on the supply). + /// There can be multiple tokens with the same id (unless supply is 1). Each token's + /// corresponding token metadata is stored inside a TokenData inside TokenDataCollection + /// under the creator's address. + /// The TokenData might be inlined together with the token in case the token is unique, i.e., its balance is 1 + /// (we might choose to extend inlining for the non-unique NFTs in future). + /// The TokenData can also be separated out to a separate creator's collection in order to normalize the + /// data layout: we'd want to keep a single instance of the token data in case its balance is large. + struct Token has key, store { + id: guid::ID, + balance: u64, + token_data: Option>, + } + + /// Struct representing data of a specific token with token_id, + /// stored under the creator's address inside TokenDataCollection. + /// For each token_id, there is only one TokenData. + struct TokenData has key, store { + metadata: TokenType, + /// Identifier for the token. + token_id: guid::GUID, + /// Pointer to where the content and metadata is stored. + content_uri: vector, + supply: u64, + /// Parent NFT id + parent_id: Option + } + + /// The data of the NFT tokens is either kept inline (in case their balance is 1), or is detached and kept + /// in the token data collection by the original creator. + struct TokenDataCollection has key { + tokens: vector>, + } + + struct MintEvent has copy, drop, store { + id: guid::ID, + creator: address, + content_uri: vector, + amount: u64, + } + + struct TransferEvent has copy, drop, store { + id: guid::ID, + from: address, + to: address, + amount: u64, + } + + struct Admin has key { + mint_events: event::EventHandle, + transfer_events: event::EventHandle, + } + + /// Indicates that a user allows creation delegation for a given TokenType + struct CreationDelegation has key, store { + guid_capability: guid::CreateCapability, + } + + const ADMIN: address = @0xa550c18; + const MAX_U64: u64 = 18446744073709551615u64; + // Error codes + /// Function can only be called by the admin address + const ENOT_ADMIN: u64 = 0; + const EWRONG_TOKEN_ID: u64 = 1; + const ETOKEN_BALANCE_OVERFLOWS: u64 = 2; + const EAMOUNT_EXCEEDS_TOKEN_BALANCE: u64 = 3; + const ETOKEN_EXTRACTED: u64 = 4; + const EINDEX_EXCEEDS_LENGTH: u64 = 5; + const ETOKEN_PRESENT: u64 = 6; + const EPARENT_NOT_SAME_ACCOUNT: u64 = 7; + const ETOKEN_DATA_COLLECTION_ALREADY_PUBLISHED: u64 = 8; + /// Creation delegation for a given token type is not allowed. + const ECREATION_DELEGATION_NOT_ALLOWED: u64 = 9; + /// Trying to merge or split tokens with inlined data. + const EINLINE_DATA_OP: u64 = 10; + + /// Initialize this module + public entry fun nft_initialize(account: signer) { + assert!(signer::address_of(&account) == ADMIN, ENOT_ADMIN); + move_to(&account, Admin { + mint_events: event::new_event_handle(&account), + transfer_events: event::new_event_handle(&account), + }) + } + + /// Returns the id of given token + public fun id(token: &Token): guid::ID { + *&token.id + } + + /// Returns the balance of given token + public fun get_balance(token: &Token): u64 { + token.balance + } + + /// Returns the overall supply for the given token + public fun get_supply(token: &Token): u64 acquires TokenDataCollection{ + if (option::is_some(&token.token_data)) { + option::borrow(&token.token_data).supply + } else { + let creator_addr = guid::id_creator_address(&token.id); + let creator_tokens_data = &borrow_global>(creator_addr).tokens; + let token_data_idx = *option::borrow(&index_of_token(creator_tokens_data, &token.id)); + vector::borrow(creator_tokens_data, token_data_idx).supply + } + } + + /// Returns a copy of the token content uri + public fun get_content_uri(token: &Token): vector acquires TokenDataCollection { + if (option::is_some(&token.token_data)) { + *&option::borrow(&token.token_data).content_uri + } else { + let creator_addr = guid::id_creator_address(&token.id); + let creator_tokens_data = &borrow_global>(creator_addr).tokens; + let token_data_idx = *option::borrow(&index_of_token(creator_tokens_data, &token.id)); + *&vector::borrow(creator_tokens_data, token_data_idx).content_uri + } + } + + /// Returns a copy of the token metadata + public fun get_metadata(token: &Token): TokenType acquires TokenDataCollection { + if (option::is_some(&token.token_data)) { + *&option::borrow(&token.token_data).metadata + } else { + let creator_addr = guid::id_creator_address(&token.id); + let creator_tokens_data = &borrow_global>(creator_addr).tokens; + let token_data_idx = *option::borrow(&index_of_token(creator_tokens_data, &token.id)); + *&vector::borrow(creator_tokens_data, token_data_idx).metadata + } + } + + /// Returns a copy of the token metadata + public fun get_parent_id(token: &Token): Option acquires TokenDataCollection { + if (option::is_some(&token.token_data)) { + *&option::borrow(&token.token_data).parent_id + } else { + let creator_addr = guid::id_creator_address(&token.id); + let creator_tokens_data = &borrow_global>(creator_addr).tokens; + let token_data_idx = *option::borrow(&index_of_token(creator_tokens_data, &token.id)); + *&vector::borrow(creator_tokens_data, token_data_idx).parent_id + } + } + + /// Returns true if the token is keeping the token data inlined. + public fun is_data_inlined(token: &Token): bool { + option::is_some(&token.token_data) + } + + /// Finds the index of token with the given id in the gallery. + fun index_of_token(gallery: &vector>, id: &guid::ID): Option { + let i = 0; + let len = vector::length(gallery); + while (i < len) { + if (guid::eq_id(&vector::borrow(gallery, i).token_id, id)) { + return option::some(i) + }; + i = i + 1; + }; + option::none() + } + + /// Adds the balance of `TokenID` to the balance of the given `Token`. + public fun join(token: &mut Token, other: Token) { + let Token { id, balance, token_data } = other; + // Inlining is allowed for single-token NFTs only. + option::destroy_none(token_data); // aborts in case token data is not None + assert!(option::is_none(&token.token_data), EINLINE_DATA_OP); + assert!(*&token.id == id, EWRONG_TOKEN_ID); + assert!(MAX_U64 - token.balance >= balance, ETOKEN_BALANCE_OVERFLOWS); + token.balance = token.balance + balance; + } + + /// Split out a new token with the given amount from the original token. + /// Aborts in case amount is greater or equal than the given token balance. + public fun split_out(token: &mut Token, amount: u64): Token { + assert!(token.balance >= amount, EAMOUNT_EXCEEDS_TOKEN_BALANCE); + assert!(option::is_none(&token.token_data), EINLINE_DATA_OP); + + token.balance = token.balance - amount; + Token { + id: *&token.id, + balance: amount, + token_data: option::none(), + } + } + + /// Create an NFT on behalf of the given user, in case a user explicitly approved this delegation for the given + /// NFT type. + /// Only the entity, which can create an object of `TokenType`, will be able to call this function. + public fun create_for( + creator: address, metadata: TokenType, content_uri: vector, amount: u64, parent_id: Option + ): Token acquires CreationDelegation, Admin, TokenDataCollection { + assert! (exists>(creator), ECREATION_DELEGATION_NOT_ALLOWED); + let guid_creation_cap = &borrow_global>(creator).guid_capability; + let guid = guid::create_with_capability(creator, guid_creation_cap); + create_impl( + creator, + guid, + metadata, + content_uri, + amount, + parent_id + ) + } + + /// Create a` TokenData` that wraps `metadata` and with balance of `amount` + public fun create( + account: &signer, metadata: TokenType, content_uri: vector, amount: u64, parent_id: Option + ): Token acquires Admin, TokenDataCollection { + let guid = guid::create(account); + if (!exists>(signer::address_of(account))) { + move_to(account, TokenDataCollection { tokens: vector::empty>() }); + }; + create_impl( + signer::address_of(account), + guid, + metadata, + content_uri, + amount, + parent_id + ) + } + + fun create_impl( + addr: address, + guid: guid::GUID, + metadata: TokenType, + content_uri: vector, + amount: u64, + parent_id: Option + ): Token acquires Admin, TokenDataCollection { + event::emit_event( + &mut borrow_global_mut(ADMIN).mint_events, + MintEvent { + id: guid::id(&guid), + creator: addr, + content_uri: copy content_uri, + amount, + } + ); + let id = guid::id(&guid); + let token_data = TokenData { metadata, token_id: guid, content_uri, supply: amount, parent_id }; + if (amount == 1) { + // inline token data + Token { id, balance: amount, token_data: option::some(token_data) } + } else { + // keep token data in the collection of the creator + let token_data_collection = &mut borrow_global_mut>(addr).tokens; + vector::push_back(token_data_collection, token_data); + Token { id, balance: amount, token_data: option::none() } + } + } + + public fun publish_token_data_collection(account: &signer) { + assert!( + !exists>(signer::address_of(account)), + ETOKEN_DATA_COLLECTION_ALREADY_PUBLISHED + ); + move_to(account, TokenDataCollection { tokens: vector::empty() }); + } + + /// Allow creation delegation for a given TokenType (the entity, which can generate a metadata of a given TokenType + /// is going to be allowed to create an NFT on behalf of the user). + /// This is useful in case a user is using a 3rd party app, which can create NFTs on their behalf. + public fun allow_creation_delegation(account: &signer) { + if (!exists>(signer::address_of(account))) { + move_to(account, CreationDelegation { guid_capability: guid::gen_create_capability(account) }); + // In order to support creation delegation, prepare the token data collection ahead of time. + if (!exists>(signer::address_of(account))) { + move_to(account, TokenDataCollection { tokens: vector::empty>() }); + }; + }; + } + + public fun emit_transfer_event( + guid: &guid::ID, + account: &signer, + to: address, + amount: u64, + ) acquires Admin { + event::emit_event( + &mut borrow_global_mut(ADMIN).transfer_events, + TransferEvent { + id: *guid, + from: signer::address_of(account), + to: to, + amount: amount, + } + ); + } + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/NFTGallery.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/NFTGallery.move new file mode 100644 index 000000000..04fad2330 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/NFTGallery.move @@ -0,0 +1,159 @@ +module 0x1::NFTGallery { + use std::guid; + use 0x1::NFT::{Self, Token}; + use std::option::{Self, Option}; + use std::signer; + use std::vector; + + /// Gallery holding tokens of `TokenType` as well as information of approved operators. + struct NFTGallery has key { + gallery: vector> + } + + // Error codes + const EID_NOT_FOUND: u64 = 0; + const EGALLERY_NOT_PUBLISHED: u64 = 1; + const EGALLERY_ALREADY_PUBLISHED: u64 = 2; + const EINVALID_AMOUNT_OF_TRANSFER: u64 = 3; + + /// Add a token to the owner's gallery. + /// The specifics of the addition depend on the token data inlining. + /// In case the token data is inlined, the addition is trivial (join / split operations are not allowed). + /// Otherwise, the addition might include joining of the two tokens. + public fun add_to_gallery(owner: address, token: Token) + acquires NFTGallery { + assert!(exists>(owner), EGALLERY_NOT_PUBLISHED); + let gallery = &mut borrow_global_mut>(owner).gallery; + if (!NFT::is_data_inlined(&token)) { + let index_opt = index_of_token(gallery, &NFT::id(&token)); + if (option::is_some(&index_opt)) { + let prev_token_idx = option::extract(&mut index_opt); + // The gallery already has the given token: update its balance + NFT::join(vector::borrow_mut(gallery, prev_token_idx), token); + return + } + }; + vector::push_back(gallery, token) + } + + /// Returns whether the owner has a token with given id. + public fun has_token(owner: address, token_id: &guid::ID): bool acquires NFTGallery { + option::is_some(&index_of_token(&borrow_global>(owner).gallery, token_id)) + } + + public fun get_token_balance(owner: address, token_id: &guid::ID + ): u64 acquires NFTGallery { + let gallery = &borrow_global>(owner).gallery; + let index_opt = index_of_token(gallery, token_id); + if (option::is_none(&index_opt)) { + 0 + } else { + let token = vector::borrow(gallery, option::extract(&mut index_opt)); + NFT::get_balance(token) + } + } + + /// Returns the overall supply for the given token (across this and potentially other galleries), + // aborts if token with the given ID is not found. + public fun get_token_supply(owner: address, token_id: &guid::ID): u64 acquires NFTGallery { + let gallery = &borrow_global>(owner).gallery; + let index_opt = index_of_token(gallery, token_id); + assert!(option::is_some(&index_opt), EID_NOT_FOUND); + let token = vector::borrow(gallery, option::extract(&mut index_opt)); + NFT::get_supply(token) + } + + /// Returns a copy of the token content uri + public fun get_token_content_uri(owner: address, token_id: &guid::ID): vector acquires NFTGallery { + let gallery = &borrow_global>(owner).gallery; + let index_opt = index_of_token(gallery, token_id); + assert!(option::is_some(&index_opt), EID_NOT_FOUND); + let token = vector::borrow(gallery, option::extract(&mut index_opt)); + NFT::get_content_uri(token) + } + + /// Returns a copy of the token metadata + public fun get_token_metadata(owner: address, token_id: &guid::ID): TokenType acquires NFTGallery { + let gallery = &borrow_global>(owner).gallery; + let index_opt = index_of_token(gallery, token_id); + assert!(option::is_some(&index_opt), EID_NOT_FOUND); + let token = vector::borrow(gallery, option::extract(&mut index_opt)); + NFT::get_metadata(token) + } + + /// Returns a copy of the token parent id + public fun get_token_parent_id(owner: address, token_id: &guid::ID): Option acquires NFTGallery { + let gallery = &borrow_global>(owner).gallery; + let index_opt = index_of_token(gallery, token_id); + assert!(option::is_some(&index_opt), EID_NOT_FOUND); + let token = vector::borrow(gallery, option::extract(&mut index_opt)); + NFT::get_parent_id(token) + } + + /// Transfer `amount` of token with id `GUID::id(creator, creation_num)` from `owner`'s + /// balance to `to`'s balance. This operation has to be done by either the owner or an + /// approved operator of the owner. + public entry fun transfer_token_between_galleries( + account: signer, + to: address, + amount: u64, + creator: address, + creation_num: u64 + ) acquires NFTGallery { + transfer_token_between_galleries_impl(&account, to, amount, creator, creation_num) + } + + /// The implementation, which doesn't consume signer, and thus can be used for testing. + public fun transfer_token_between_galleries_impl( + account: &signer, + to: address, + amount: u64, + creator: address, + creation_num: u64 + ) acquires NFTGallery { + let owner = signer::address_of(account); + assert!(amount > 0, EINVALID_AMOUNT_OF_TRANSFER); + let gallery = &mut borrow_global_mut>(owner).gallery; + let id = guid::create_id(creator, creation_num); + + let index_opt = index_of_token(gallery, &id); + assert!(option::is_some(&index_opt), EID_NOT_FOUND); + let from_token_idx = option::extract(&mut index_opt); + + if (NFT::is_data_inlined(vector::borrow(gallery, from_token_idx)) || + NFT::get_balance(vector::borrow(gallery, from_token_idx)) == amount) { + // Move the token from one gallery to another + let token = vector::remove(gallery, from_token_idx); + add_to_gallery(to, token) + } else { + // Split the original token and add the splitted part to another gallery + let split_out_token = NFT::split_out(vector::borrow_mut(gallery, from_token_idx), amount); + add_to_gallery(to, split_out_token) + }; + // Emit transfer event + NFT::emit_transfer_event( + &id, + account, + to, + amount, + ) + } + + public fun publish_gallery(account: &signer) { + assert!(!exists>(signer::address_of(account)), EGALLERY_ALREADY_PUBLISHED); + move_to(account, NFTGallery { gallery: vector::empty() }); + } + + /// Finds the index of token with the given id in the gallery. + fun index_of_token(gallery: &vector>, id: &guid::ID): Option { + let i = 0; + let len = vector::length(gallery); + while (i < len) { + if (NFT::id(vector::borrow(gallery, i)) == *id) { + return option::some(i) + }; + i = i + 1; + }; + option::none() + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/SystemAdministrationScripts.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/SystemAdministrationScripts.move new file mode 100644 index 000000000..492eff074 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/SystemAdministrationScripts.move @@ -0,0 +1,142 @@ +/// This module contains Diem Framework script functions to administer the +/// network outside of validators and validator operators. +module ExperimentalFramework::SystemAdministrationScripts { + use ExperimentalFramework::ExperimentalConsensusConfig; + use ExperimentalFramework::ExperimentalVersion; + use ExperimentalFramework::ExperimentalVMConfig; + + /// # Summary + /// Updates the Diem major version that is stored on-chain and is used by the VM. This + /// transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Updates the `DiemVersion` on-chain config and emits a `DiemConfig::NewEpochEvent` to trigger + /// a reconfiguration of the system. The `major` version that is passed in must be strictly greater + /// than the current major version held on-chain. The VM reads this information and can use it to + /// preserve backwards compatibility with previous major versions of the VM. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `_sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `major` | `u64` | The `major` version of the VM to be used from this transaction on. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + /// | `Errors::INVALID_ARGUMENT` | `DiemVersion::EINVALID_MAJOR_VERSION_NUMBER` | `major` is less-than or equal to the current major version stored on-chain. | + + public entry fun update_diem_version(account: signer, _sliding_nonce: u64, major: u64) { + ExperimentalVersion::set(&account, major) + } + + /// # Summary + /// Updates the gas constants stored on chain and used by the VM for gas + /// metering. This transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Updates the on-chain config holding the `DiemVMConfig` and emits a + /// `DiemConfig::NewEpochEvent` to trigger a reconfiguration of the system. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `_sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `global_memory_per_byte_cost` | `u64` | The new cost to read global memory per-byte to be used for gas metering. | + /// | `global_memory_per_byte_write_cost` | `u64` | The new cost to write global memory per-byte to be used for gas metering. | + /// | `min_transaction_gas_units` | `u64` | The new flat minimum amount of gas required for any transaction. | + /// | `large_transaction_cutoff` | `u64` | The new size over which an additional charge will be assessed for each additional byte. | + /// | `intrinsic_gas_per_byte` | `u64` | The new number of units of gas that to be charged per-byte over the new `large_transaction_cutoff`. | + /// | `maximum_number_of_gas_units` | `u64` | The new maximum number of gas units that can be set in a transaction. | + /// | `min_price_per_gas_unit` | `u64` | The new minimum gas price that can be set for a transaction. | + /// | `max_price_per_gas_unit` | `u64` | The new maximum gas price that can be set for a transaction. | + /// | `max_transaction_size_in_bytes` | `u64` | The new maximum size of a transaction that can be processed. | + /// | `gas_unit_scaling_factor` | `u64` | The new scaling factor to use when scaling between external and internal gas units. | + /// | `default_account_size` | `u64` | The new default account size to use when assessing final costs for reads and writes to global storage. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::INVALID_ARGUMENT` | `DiemVMConfig::EGAS_CONSTANT_INCONSISTENCY` | The provided gas constants are inconsistent. | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + public entry fun set_gas_constants( + dr_account: signer, + _sliding_nonce: u64, + global_memory_per_byte_cost: u64, + global_memory_per_byte_write_cost: u64, + min_transaction_gas_units: u64, + large_transaction_cutoff: u64, + intrinsic_gas_per_byte: u64, + maximum_number_of_gas_units: u64, + min_price_per_gas_unit: u64, + max_price_per_gas_unit: u64, + max_transaction_size_in_bytes: u64, + gas_unit_scaling_factor: u64, + default_account_size: u64, + ) { + ExperimentalVMConfig::set_gas_constants( + &dr_account, + global_memory_per_byte_cost, + global_memory_per_byte_write_cost, + min_transaction_gas_units, + large_transaction_cutoff, + intrinsic_gas_per_byte, + maximum_number_of_gas_units, + min_price_per_gas_unit, + max_price_per_gas_unit, + max_transaction_size_in_bytes, + gas_unit_scaling_factor, + default_account_size, + ) + } + + /// # Summary + /// Initializes the Diem consensus config that is stored on-chain. This + /// transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Initializes the `DiemConsensusConfig` on-chain config to empty and allows future updates from DiemRoot via + /// `update_diem_consensus_config`. This doesn't emit a `DiemConfig::NewEpochEvent`. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `_sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + + public entry fun initialize_diem_consensus_config(account: signer, _sliding_nonce: u64) { + ExperimentalConsensusConfig::initialize(&account); + } + + /// # Summary + /// Updates the Diem consensus config that is stored on-chain and is used by the Consensus. This + /// transaction can only be sent from the Diem Root account. + /// + /// # Technical Description + /// Updates the `DiemConsensusConfig` on-chain config and emits a `DiemConfig::NewEpochEvent` to trigger + /// a reconfiguration of the system. + /// + /// # Parameters + /// | Name | Type | Description | + /// | ------ | ------ | ------------- | + /// | `account` | `signer` | Signer of the sending account. Must be the Diem Root account. | + /// | `_sliding_nonce` | `u64` | The `sliding_nonce` (see: `SlidingNonce`) to be used for this transaction. | + /// | `config` | `vector` | The serialized bytes of consensus config. | + /// + /// # Common Abort Conditions + /// | Error Category | Error Reason | Description | + /// | ---------------- | -------------- | ------------- | + /// | `Errors::REQUIRES_ADDRESS` | `CoreAddresses::EDIEM_ROOT` | `account` is not the Diem Root account. | + + public entry fun update_diem_consensus_config(account: signer, _sliding_nonce: u64, config: vector) { + ExperimentalConsensusConfig::set(&account, config) + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/Vote.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/Vote.move new file mode 100644 index 000000000..b3f55c9e0 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/Vote.move @@ -0,0 +1,654 @@ +/// The Vote module is used to allow voting on proposals on the chain. +/// It is typically not going to be used directly, but is intended to be +/// used as a library for modules which want to perform operations which +/// require m-of-n approvals from accounts on chain. +/// A typical workflow would look like the following +/// * Module M creates a ballot with a given `Proposal` and an approval policy using `create_ballot` +/// * It receives the BallotID corresponding to the ballot +/// * It submits votes using the `vote` function from the voters +/// * If a vote causes a ballot to be approved, `vote` returns `true` and Module M can proceed with the operation requested by the `Proposal` +module ExperimentalFramework::Vote { + + use std::bcs; + use std::errors; + use std::event; + use std::signer; + use std::vector; + use CoreFramework::DiemTimestamp; + #[test_only] + friend ExperimentalFramework::VoteTests; + + /// An unique identifier for a ballot. A counter is stored + /// under each proposers address which is incremented + /// every time a new ballot is created. The proposers + /// address is also part of the ballot id. + struct BallotID has store, copy, drop { + counter: u64, + proposer: address, + } + + /// WeightedVoter represents a voter with a weight + /// The voter is represented by the bcs serialization of address + struct WeightedVoter has store, copy, drop { + weight: u64, + voter: vector, + } + + /// Ballot is a struct which contains a Proposal on which + /// votes are gathered. A ballot is started by a proposer + /// and it carries the proposal, the approval policy, + /// expiration timestamp + struct Ballot has store, copy, drop { + /// Details for the proposal being voted on. + proposal: Proposal, + /// A human readable type for the proposal - ex: "create_validator_owner", + /// "freeze_account", "create_vasp", etc. + /// This lives outside the `proposal: Proposal` to make it easy for + /// indexers to index the ballots which have been proposed and + /// categorize them into "types" + proposal_type: vector, + /// The num_votes_required for this proposal to be approved + num_votes_required: u64, + /// A vector of addresses which are allowed to vote on this ballot. + allowed_voters: vector, + /// Votes received so far + votes_received: vector, + /// Total number of weighted votes received + total_weighted_votes_received: u64, + // A globally unique ballot id that is created for every proposal + ballot_id: BallotID, + // Votes rejected after this time + expiration_timestamp_secs: u64, + } + + /// Ballots stores a list of ballots under a proposers address. + /// It is type parametrized by the Proposal. Some of these may + /// be expired and can be cleaned up using the `gc_ballots` function + /// It also contains the handles for all the events associated + /// with the ballots created by a proposer + struct Ballots has key { + ballots: vector>, + create_ballot_handle: event::EventHandle>, + remove_ballot_handle: event::EventHandle, + voted_handle: event::EventHandle, + ballot_approved_handle: event::EventHandle, + } + + /// A counter which is stored under the proposers address and gets incremented + /// everytime they create a new ballot. This is used for creating unique + /// global identifiers for Ballots + struct BallotCounter has key { + counter: u64, + } + + /// CreateBallotEvent is emitted when a ballot is + /// created by a proposer + struct CreateBallotEvent has drop, store { + ballot_id: BallotID, + ballot: Ballot, + } + + /// RemoveBallotEvent is emitted when a ballot has + /// been removed. This can either happen because: + /// * ballot was approved + /// * ballot was manually removed by the proposer + /// * ballot was expired and garbage collected + struct RemoveBallotEvent has drop, store { + ballot_id: BallotID, + } + + /// VotedEvent is emitted when a valid vote has + /// been accepted by the ballot + struct VotedEvent has drop, store { + ballot_id: BallotID, + voter: address, + vote_weight: u64, + } + + /// BallotApprovedEvent is emitted when a ballot has + /// been approved by the voters + struct BallotApprovedEvent has drop, store { + ballot_id: BallotID, + } + + /// The maximum number of ballots allowed per proposal type + /// per address. + const MAX_BALLOTS_PER_PROPOSAL_TYPE_PER_ADDRESS: u64 = 256; + + /// The provided timestamp(s) were invalid + const EINVALID_TIMESTAMP: u64 = 1; + /// The address already contains has the maximum of ballots allowed + /// MAX_BALLOTS_PER_PROPOSAL_TYPE_PER_ADDRESS + const ETOO_MANY_BALLOTS: u64 = 2; + /// Ballot with the provided id was not found + const EBALLOT_NOT_FOUND: u64 = 3; + /// Proposal details in the vote do not match the proposal details + /// in the ballot + const EBALLOT_PROPOSAL_MISMATCH: u64 = 4; + /// Voter not allowed to vote in the ballot + const EINVALID_VOTER: u64 = 5; + /// current timestamp > ballot expiration time + const EBALLOT_EXPIRED: u64 = 7; + /// Voter has already voted in this ballot + const EALREADY_VOTED: u64 = 8; + /// Num_votes must be greater than 0, so that election is not won when started + const EINVALID_NUM_VOTES: u64 = 9; + + /// A constructor for BallotID + public fun new_ballot_id( + counter: u64, + proposer: address, + ): BallotID { + BallotID { + counter, + proposer, + } + } + + /// A constructor for WeightedVoter + public fun new_weighted_voter( + weight: u64, + voter: vector, + ): WeightedVoter { + WeightedVoter { + weight, + voter, + } + } + + /// Create a ballot under the signer's address and return the `BallotID` + public fun create_ballot( + ballot_account: &signer, + proposal: Proposal, + proposal_type: vector, + num_votes_required: u64, + allowed_voters: vector, + expiration_timestamp_secs: u64 + ): BallotID acquires Ballots, BallotCounter { + let ballot_address = signer::address_of(ballot_account); + + assert!(DiemTimestamp::now_seconds() < expiration_timestamp_secs, errors::invalid_argument(EINVALID_TIMESTAMP)); + assert!(num_votes_required > 0, errors::invalid_argument(EINVALID_NUM_VOTES)); + + if (!exists(ballot_address)) { + move_to(ballot_account, BallotCounter { + counter: 0, + }); + }; + if (!exists>(ballot_address)) { + move_to(ballot_account, Ballots { + ballots: vector::empty(), + create_ballot_handle: event::new_event_handle>(ballot_account), + remove_ballot_handle: event::new_event_handle(ballot_account), + voted_handle: event::new_event_handle(ballot_account), + ballot_approved_handle: event::new_event_handle(ballot_account), + }); + }; + + let ballot_data = borrow_global_mut>(ballot_address); + + // Remove any expired ballots + gc_internal(ballot_data); + let ballots = &mut ballot_data.ballots; + + assert!(vector::length(ballots) < MAX_BALLOTS_PER_PROPOSAL_TYPE_PER_ADDRESS, errors::limit_exceeded(ETOO_MANY_BALLOTS)); + let ballot_id = new_ballot_id(incr_counter(ballot_account), ballot_address); + let ballot = Ballot { + proposal, + proposal_type, + num_votes_required, + allowed_voters, + votes_received: vector::empty(), + total_weighted_votes_received: 0, + ballot_id: *&ballot_id, + expiration_timestamp_secs, + }; + vector::push_back(ballots, *&ballot); + event::emit_event>( + &mut ballot_data.create_ballot_handle, + CreateBallotEvent { + ballot_id: *&ballot_id, + ballot, + }, + ); + ballot_id + } + + // Checks if a voter is present in the vector + fun check_voter_present( + weighted_voters: &vector, + voter: &vector, + ): bool { + let i = 0; + let len = vector::length(weighted_voters); + while (i < len) { + if (&vector::borrow(weighted_voters, i).voter == voter) return true; + i = i + 1; + }; + false + } + + /// Submit a vote from the `voter_account` to `ballot_id` + /// This also contains the `proposal_type` and `proposal` so that + /// the voter signs over these when sending their vote. + /// If this vote causes the ballot to be approved, then the ballot + /// is removed from the proposers address. + /// This returns a bool indicating whether this vote moved the ballot + /// to an approved status. true represents that the ballot got approved + /// after this vote and false represents that the ballot has not been + /// approved after this vote + public fun vote( + voter_account: &signer, + ballot_id: BallotID, + proposal_type: vector, + proposal: Proposal, + ): bool acquires Ballots { + let ballot_data = borrow_global_mut>(ballot_id.proposer); + + // Remove any expired ballots + gc_internal(ballot_data); + + let ballots = &mut ballot_data.ballots; + let i = 0; + let len = vector::length(ballots); + while (i < len) { + if (&vector::borrow(ballots, i).ballot_id == &ballot_id) break; + i = i + 1; + }; + assert!(i < len, errors::invalid_state(EBALLOT_NOT_FOUND)); + let ballot_index = i; + let ballot = vector::borrow_mut(ballots, ballot_index); + + assert!(&ballot.proposal == &proposal, errors::invalid_argument(EBALLOT_PROPOSAL_MISMATCH)); + assert!(&ballot.proposal_type == &proposal_type, errors::invalid_argument(EBALLOT_PROPOSAL_MISMATCH)); + + let voter_address = signer::address_of(voter_account); + let voter_address_bcs = bcs::to_bytes(&voter_address); + let allowed_voters = &ballot.allowed_voters; + + assert!(check_voter_present(allowed_voters, &voter_address_bcs), errors::invalid_state(EINVALID_VOTER)); + assert!(DiemTimestamp::now_seconds() <= ballot.expiration_timestamp_secs, errors::invalid_state(EBALLOT_EXPIRED)); + + assert!(!check_voter_present(&ballot.votes_received, &voter_address_bcs), errors::invalid_state(EALREADY_VOTED)); + + let i = 0; + let len = vector::length(allowed_voters); + while (i < len) { + let weighted_voter = vector::borrow(allowed_voters, i); + if (&weighted_voter.voter == &voter_address_bcs) { + vector::push_back(&mut ballot.votes_received, *weighted_voter); + ballot.total_weighted_votes_received = ballot.total_weighted_votes_received + weighted_voter.weight; + event::emit_event( + &mut ballot_data.voted_handle, + VotedEvent { + ballot_id: *&ballot_id, + voter: voter_address, + vote_weight: weighted_voter.weight, + }, + ); + break + }; + i = i + 1; + }; + let ballot_approved = ballot.total_weighted_votes_received >= ballot.num_votes_required; + // If the ballot gets approved, remove the ballot immediately + if (ballot_approved) { + vector::swap_remove(ballots, ballot_index); + event::emit_event( + &mut ballot_data.ballot_approved_handle, + BallotApprovedEvent { + ballot_id, + }, + ); + }; + ballot_approved + } + + /// gc_ballots deletes all the expired ballots of the type `Proposal` + /// under the provided address `addr`. The signer can be anybody + /// and does not need to have the same address as `addr` + public entry fun gc_ballots( + _signer: signer, + addr: address, + ) acquires Ballots { + gc_internal(borrow_global_mut>(addr)); + } + + public(friend) fun gc_test_helper( + addr: address, + ): vector acquires Ballots { + gc_internal(borrow_global_mut>(addr)) + } + + fun gc_internal( + ballot_data: &mut Ballots, + ): vector { + let ballots = &mut ballot_data.ballots; + let remove_handle = &mut ballot_data.remove_ballot_handle; + let i = 0; + let removed_ballots = vector::empty(); + while ({ + spec { + invariant unique_ballots(ballots); + invariant no_expired_ballots(ballots, DiemTimestamp::spec_now_seconds(), i); + invariant vector_subset(ballots, old(ballot_data).ballots); + invariant i <= len(ballots); + invariant 0 <= i; + }; + i < vector::length(ballots) + }) { + let ballot = vector::borrow(ballots, i); + if (ballot.expiration_timestamp_secs < DiemTimestamp::now_seconds()) { + let ballot_id = *(&ballot.ballot_id); + vector::swap_remove(ballots, i); + vector::push_back(&mut removed_ballots, *&ballot_id); + event::emit_event( + remove_handle, + RemoveBallotEvent { + ballot_id + }, + ); + } else { + i = i + 1; + }; + }; + removed_ballots + } + + public(friend) fun remove_ballot_internal( + account: signer, + ballot_id: BallotID, + ) acquires Ballots { + let addr = signer::address_of(&account); + let ballot_data = borrow_global_mut>(addr); + let ballots = &mut ballot_data.ballots; + let remove_handle = &mut ballot_data.remove_ballot_handle; + let i = 0; + let len = vector::length(ballots); + while ({ + spec { invariant ballot_id_does_not_exist(ballot_id, ballots, i); }; + i < len + }) { + if (&vector::borrow(ballots, i).ballot_id == &ballot_id) { + vector::swap_remove(ballots, i); + event::emit_event( + remove_handle, + RemoveBallotEvent { + ballot_id + }, + ); + return () + }; + i = i + 1; + }; + } + + /// remove_ballot removes the ballot with the provided + /// `ballot_id` from the address of the provided `account` + /// If a ballot with `ballot_id` is not found, then it + /// does nothing + public fun remove_ballot( + account: signer, + ballot_id: BallotID, + ) acquires Ballots { + remove_ballot_internal(account, ballot_id) + } + + /// incr_counter increments the counter stored under the signer's + /// account + fun incr_counter(account: &signer): u64 acquires BallotCounter { + let addr = signer::address_of(account); + let counter = &mut borrow_global_mut(addr).counter; + let count = *counter; + *counter = *counter + 1; + count + } + + ///**************************************************************** + /// Specs + ///**************************************************************** + + /// I (DD) was experimenting with some new ideas about top-down specification. + /// This is a partial specification, but it does have some interesting properties + /// and is good for testing the Prover. + + /// A "Ballot" keeps track of an election for a "Proposal" type at a particular address. + + /// To conduct an election at a particular address, there must be a BallotCounter + /// published at that address. This keeps track of a counter that is used to generate + /// unique BallotIDs. + + spec module { + /// Once the BallotCounter is published, it remains published forever + invariant update forall ballot_addr: address where old(exists(ballot_addr)): + exists(ballot_addr); + + /// Once a proposal is initialized, it stays initialized forever. + invariant update forall ballot_addr: address + where old(exists>(ballot_addr)): + exists>(ballot_addr); + } + + /// Predicate to test if a `Ballots` resource for `Proposal` is published at `ballot_addr`, + /// there is a `BallotCounter` published at `ballot_addr`. + spec fun ballot_counter_initialized_first(ballot_addr: address): bool { + exists>(ballot_addr) ==> exists(ballot_addr) + } + + spec module { + // / Whenever there is a Ballots at ballot_address, there is + // / a BallotCounter there. + // TODO: Because of prover bug, this is temporarily ANDed with another invariant. + // invariant forall ballot_addr: address: + // ballot_counter_initialized_first(ballot_addr); + } + + // UTILITY FUNCTIONS + + /// Get the ballots vector from published Ballots + /// CAUTION: Returns an arbitrary value if no Ballots is publised at ballot_address. + spec fun get_ballots(ballot_address: address): vector> { + global>(ballot_address).ballots + } + + /// Get the ballot matching ballot_id out of the ballots vector, if it is there. + /// CAUTION: Returns a arbitrary value if it's not there. + spec fun get_ballot(ballot_address: address, ballot_id: BallotID): Ballot { + let ballots = global>(ballot_address).ballots; + get_ballots(ballot_address)[choose min i in 0..len(ballots) where ballots[i].ballot_id == ballot_id] + } + + /// Tests whether ballot_id is represented in the ballots vector. Returns false if there is no + /// ballots vector. + spec fun ballot_exists(ballot_address: address, ballot_id: BallotID): bool { + if (exists>(ballot_address)) { + let ballots = global>(ballot_address).ballots; + exists i in 0..len(ballots): ballots[i].ballot_id == ballot_id + } + else + false + } + + /// Assuming ballot exists, check if it's expired. Returns an arbitrary result if the + /// ballot does not exist. + /// NOTE: Maybe this should be "<=" not "<" + spec fun is_expired_if_exists(ballot_address: address, ballot_id: BallotID): bool { + get_ballot(ballot_address, ballot_id).expiration_timestamp_secs + <= DiemTimestamp::spec_now_seconds() + } + + // FUNCTIONS REPRESENTING STATES + + /// There is a state machine for every `BallotID`. Two of the states don't + /// need to appear in formal specifications, but they are here for completeness. + /// State: unborn -- The `BallotID` has a count that is greater than the count in BallotCounter. + /// So the `BallotID` has not yet been generated, and may be generated in the future. + /// It is not in use, so we won't see values in this state. + /// A `BallotID` in the unborn state may transition to the active state if `create_ballot` + /// generates that `BallotID`. + /// State: dead -- The `BallotID` was generated and then was either and accepted (when + /// a call to `vote` causes the vote total to exceed the threshold), + /// or expired and garbage collected. So, it is no longer in use and we won't see these + /// values. Note that garbage collection occurs in several functions. + /// State active -- The `BallotID` is in a `Ballots.ballots` vector for some Proposal and + /// address. It is not expired and may eventually be accepted. + /// Active BallotIDs are created and returned by `create_ballot`. + /// An active `BallotID` may transition to the expired state if it is not accepted and the current + /// time exceeds its expiration time, or it may transition to the dead state if it expires and is + /// garbage-collected in the same transaction or if it is accepted. + /// State expired -- The `BallotID` is in a `Ballots.ballots` vector for some Proposal and + /// address but is expired. It will be removed from the ballots vector and change to the dead state + /// if and when it is garbage-collected. + + /// A BallotID is in the expired state if it is in the ballots vector and the + /// current time is >= the expiration time. + spec fun is_expired(ballot_address: address, ballot_id: BallotID): bool { + ballot_exists(ballot_address, ballot_id) + && is_expired_if_exists(ballot_address, ballot_id) + } + + /// A BallotID is active state if it is in the ballots vector and not expired. + spec fun is_active(ballot_address: address, ballot_id: BallotID): bool { + ballot_exists(ballot_address, ballot_id) + && !is_expired_if_exists(ballot_address, ballot_id) + } + + spec create_ballot { + /// create_ballot sets up a `Ballots` resource at the `ballot_account` + /// address if one does not already exist. + ensures exists>(signer::address_of(ballot_account)); + + /// returns a new active `BallotID`. + ensures is_active(signer::address_of(ballot_account), result); + } + + /// Returns "true" iff there are no ballots in v at indices less than i whose + /// expiration time is less than or equal to the current time. + spec fun no_expired_ballots(ballots: vector>, now_seconds: u64, i: u64): bool { + forall j in 0..i: ballots[j].expiration_timestamp_secs >= now_seconds + } + + // This is equivalent to mapping each ballot in v to its ballot_id. + // TODO: A map operation in the spec language would be much clearer. + spec fun extract_ballot_ids(v: vector>): vector { + choose result: vector where len(result) == len(v) + && (forall i in 0..len(v): result[i] == v[i].ballot_id) + } + + /// Common post-conditions for `gc_internal` and `gc_ballots` (which just calls `gc_internal`) + spec schema GcEnsures { + ballot_data: Ballots; + let pre_ballots = ballot_data.ballots; + let post post_ballots = ballot_data.ballots; + + /// Ballots afterwards is a subset of ballots before. + ensures vector_subset(post_ballots, pre_ballots); + /// All expired ballots are removed + ensures no_expired_ballots(post_ballots, DiemTimestamp::spec_now_seconds(), len(post_ballots)); + } + + spec gc_internal { + pragma opaque; + include GcEnsures; + // Note: There is no specification of returned vector of removed ballot ids, because + // return value seems not to be used. + } + + spec gc_ballots { + include GcEnsures{ballot_data: global>(addr)}; + } + + // Lower-level invariants + + // helper functions + + spec fun ballot_ids_have_correct_ballot_address(proposer_address: address): bool { + let ballots = get_ballots(proposer_address); + forall i in 0..len(ballots): ballots[i].ballot_id.proposer == proposer_address + } + + /// Every ballot for Proposal at proposer_address has a ballot counter field that is less + /// than the current value of the BallotCounter.counter published at proposer_address. + /// This property is necessary to show that the ballot IDs are not repeated in the + /// Ballots.ballots vector + spec fun existing_ballots_have_small_counters(proposer_address: address): bool { + // Just return true if there is no Ballots published at proposer_address + // get_ballots may be undefined here, but we only use it when we know the Ballots + // is published (in the next property. + let ballots = get_ballots(proposer_address); + exists>(proposer_address) + ==> (forall i in 0..len(ballots): + ballots[i].ballot_id.counter < global(proposer_address).counter) + } + + /// Every ballot in Ballots.ballots is active or expired. + /// I.e., none have sum >= required. + /// TODO: This should be part of is_active/expired, and should follow from an invariant + /// that every BallotID is in one of the legal states. + spec fun no_winning_ballots_in_vector(proposer_address: address): bool { + let ballots = get_ballots(proposer_address); + forall i in 0..len(ballots): + ballots[i].total_weighted_votes_received < ballots[i].num_votes_required + } + + spec module { + /// ballots in vector all have the proposer address in their ballot IDs. + invariant [suspendable] forall proposer_address: address: + ballot_ids_have_correct_ballot_address(proposer_address); + + // / counter values in ballots are all less than the value of the BallotCounter + // / See note on spec fun existing_ballots_have_small_counters + // TODO: Temporarily commented out because of a prover bug. It is included in + // the next property + // invariant forall addr: address: existing_ballots_have_small_counters(addr); + + // AND of these two invariants works, but they don't if individual due to a bug. + invariant + (forall addr: address: existing_ballots_have_small_counters(addr)) + && (forall ballot_addr: address: ballot_counter_initialized_first(ballot_addr)); + + /// Every ballot in the vector has total_weighted_votes_received < num_votes_required + /// So the ballot will eventually be removed either by accumulating enough votes or by expiring + /// and being garbage-collected + invariant forall addr: address: no_winning_ballots_in_vector(addr); + } + + /// There are no duplicate Ballot IDs in the Ballots.ballots vector + spec fun unique_ballots(ballots: vector>): bool { + forall i in 0..len(ballots), j in 0..len(ballots): + ballots[i].ballot_id == ballots[j].ballot_id ==> i == j + } + + /// All `BallotID`s of `Ballot`s in a `Ballots.ballots` vector are unique. + spec Ballots { + invariant unique_ballots(ballots); + } + + /// Asserts that ballot ID is not in ballots vector. Used in loop invariant + /// and post-condition of remove_ballot_internal + spec fun ballot_id_does_not_exist(ballot_id: BallotID, ballots: vector>, i: u64): bool { + forall j in 0..i: ballots[j].ballot_id != ballot_id + } + + spec remove_ballot_internal { + let post ballots = get_ballots(signer::address_of(account)); + ensures + ballot_id_does_not_exist(ballot_id, ballots, len(ballots)); + } + + spec remove_ballot { + let post ballots = get_ballots(signer::address_of(account)); + ensures + ballot_id_does_not_exist(ballot_id, ballots, len(ballots)); + } + + spec gc_test_helper { + // Just a test function, we don't need to spec it. + pragma verify = false; + } + + // helper functions + spec fun vector_subset(v1: vector, v2: vector): bool { + forall e in v1: exists i in 0..len(v2): v2[i] == e + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalConsensusConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalConsensusConfig.move new file mode 100644 index 000000000..01e5afb05 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalConsensusConfig.move @@ -0,0 +1,17 @@ +module ExperimentalFramework::ExperimentalConsensusConfig { + use std::capability; + use CoreFramework::DiemConsensusConfig; + + struct ExperimentalConsensusConfig has drop {} + + public fun initialize(account: &signer) { + DiemConsensusConfig::initialize(account); + capability::create(account, &ExperimentalConsensusConfig {}); + } + + public fun set(account: &signer, config: vector) { + DiemConsensusConfig::set( + config, &capability::acquire(account, &ExperimentalConsensusConfig {}) + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalParallelExecutionConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalParallelExecutionConfig.move new file mode 100644 index 000000000..12214efc8 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalParallelExecutionConfig.move @@ -0,0 +1,32 @@ +module ExperimentalFramework::ExperimentalParallelExecutionConfig { + use std::capability; + use CoreFramework::ParallelExecutionConfig; + + struct ExperimentalParallelExecutionConfig has drop {} + + public fun initialize_parallel_execution( + account: &signer, + ) { + ParallelExecutionConfig::initialize_parallel_execution(account); + capability::create( + account, + &ExperimentalParallelExecutionConfig {} + ); + } + + public fun enable_parallel_execution_with_config( + account: &signer, + read_write_inference_result: vector, + ) { + ParallelExecutionConfig::enable_parallel_execution_with_config( + read_write_inference_result, + &capability::acquire(account, &ExperimentalParallelExecutionConfig {}), + ); + } + + public fun disable_parallel_execution(account: &signer) { + ParallelExecutionConfig::disable_parallel_execution( + &capability::acquire(account, &ExperimentalParallelExecutionConfig {}), + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalVMConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalVMConfig.move new file mode 100644 index 000000000..be7895119 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalVMConfig.move @@ -0,0 +1,46 @@ +module ExperimentalFramework::ExperimentalVMConfig { + use std::capability; + use CoreFramework::DiemVMConfig; + + struct ExperimentalVMConfig has drop {} + + /// Publishes the VM config. + public fun initialize( + account: &signer, + instruction_schedule: vector, + native_schedule: vector, + ) { + DiemVMConfig::initialize(account, instruction_schedule, native_schedule); + capability::create(account, &ExperimentalVMConfig {}); + } + + public fun set_gas_constants( + account: &signer, + global_memory_per_byte_cost: u64, + global_memory_per_byte_write_cost: u64, + min_transaction_gas_units: u64, + large_transaction_cutoff: u64, + intrinsic_gas_per_byte: u64, + maximum_number_of_gas_units: u64, + min_price_per_gas_unit: u64, + max_price_per_gas_unit: u64, + max_transaction_size_in_bytes: u64, + gas_unit_scaling_factor: u64, + default_account_size: u64, + ) { + DiemVMConfig::set_gas_constants( + global_memory_per_byte_cost, + global_memory_per_byte_write_cost, + min_transaction_gas_units, + large_transaction_cutoff, + intrinsic_gas_per_byte, + maximum_number_of_gas_units, + min_price_per_gas_unit, + max_price_per_gas_unit, + max_transaction_size_in_bytes, + gas_unit_scaling_factor, + default_account_size, + &capability::acquire(account, &ExperimentalVMConfig {}), + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorConfig.move new file mode 100644 index 000000000..e3a4d2a19 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorConfig.move @@ -0,0 +1,25 @@ +module ExperimentalFramework::ExperimentalValidatorConfig { + use std::capability; + use CoreFramework::ValidatorConfig; + + friend ExperimentalFramework::ExperimentalAccount; + + struct ExperimentalValidatorConfig has drop {} + + public fun initialize(account: &signer) { + ValidatorConfig::initialize(account); + capability::create(account, &ExperimentalValidatorConfig{}); + } + + public(friend) fun publish( + root_account: &signer, + validator_account: &signer, + human_name: vector, + ) { + ValidatorConfig::publish( + validator_account, + human_name, + capability::acquire(root_account, &ExperimentalValidatorConfig{}) + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorOperatorConfig.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorOperatorConfig.move new file mode 100644 index 000000000..4769ea613 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorOperatorConfig.move @@ -0,0 +1,25 @@ +module ExperimentalFramework::ExperimentalValidatorOperatorConfig { + use std::capability; + use CoreFramework::ValidatorOperatorConfig; + + friend ExperimentalFramework::ExperimentalAccount; + + struct ExperimentalValidatorOperatorConfig has drop {} + + public fun initialize(account: &signer) { + ValidatorOperatorConfig::initialize(account); + capability::create(account, &ExperimentalValidatorOperatorConfig{}); + } + + public(friend) fun publish( + root_account: &signer, + validator_operator_account: &signer, + human_name: vector, + ) { + ValidatorOperatorConfig::publish( + validator_operator_account, + human_name, + capability::acquire(root_account, &ExperimentalValidatorOperatorConfig{}) + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorSet.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorSet.move new file mode 100644 index 000000000..bdf451b77 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalValidatorSet.move @@ -0,0 +1,33 @@ +module ExperimentalFramework::ExperimentalValidatorSet { + use std::capability; + use CoreFramework::DiemSystem; + + struct ExperimentalValidatorSet has drop {} + + public fun initialize_validator_set( + account: &signer, + ) { + DiemSystem::initialize_validator_set(account); + capability::create(account, &ExperimentalValidatorSet {}); + } + + public fun add_validator( + account: &signer, + validator_addr: address, + ) { + DiemSystem::add_validator( + validator_addr, + capability::acquire(account, &ExperimentalValidatorSet {}) + ); + } + + public fun remove_validator( + account: &signer, + validator_addr: address, + ) { + DiemSystem::remove_validator( + validator_addr, + capability::acquire(account, &ExperimentalValidatorSet {}) + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalVersion.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalVersion.move new file mode 100644 index 000000000..fecbb611c --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/ExperimentalVersion.move @@ -0,0 +1,21 @@ +/// Maintains the version number for the blockchain. +module ExperimentalFramework::ExperimentalVersion { + use std::capability; + use CoreFramework::DiemVersion; + + struct ExperimentalVersion has drop {} + + /// Publishes the Version config. + public fun initialize(account: &signer, initial_version: u64) { + DiemVersion::initialize(account, initial_version); + capability::create(account, &ExperimentalVersion {}); + } + + /// Updates the major version to a larger version. + public fun set(account: &signer, major: u64) { + DiemVersion::set( + major, + &capability::acquire(account, &ExperimentalVersion {}), + ); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/README.md b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/README.md new file mode 100644 index 000000000..5dce27912 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/sources/configs/README.md @@ -0,0 +1 @@ +See [README for core](../../../core/README.md). diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/MultiTokenTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/MultiTokenTests.move new file mode 100644 index 000000000..e95b1e865 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/MultiTokenTests.move @@ -0,0 +1,103 @@ +#[test_only] +module ExperimentalFramework::MultiTokenTests { + use std::guid; + use ExperimentalFramework::MultiToken; + use ExperimentalFramework::MultiTokenBalance; + + /// A test token type to instantiate generic Tokens with. + struct Game has store { + name: vector, + edition: u64, + } + + const EMINT_FAILED: u64 = 0; + const ETRANSFER_FAILED: u64 = 1; + + #[test(admin=@0xa550c18, creator=@0x42, user=@0x43)] + public entry fun test_all(admin: signer, creator: signer, user: signer) { + /* + =============================================================== + Initialization + preparation + =============================================================== + */ + + let creator_addr = @0x42; + let user_addr = @0x43; + + MultiToken::initialize_multi_token(admin); + MultiTokenBalance::publish_balance(&creator); + MultiTokenBalance::publish_balance(&user); + + let token1_id = guid::create_id(creator_addr, 0); + let token2_id = guid::create_id(creator_addr, 1); + + /* + =============================================================== + Test minting + =============================================================== + */ + + let token1 = MultiToken::create( + &creator, + Game { name: b"Mario", edition: 2008 }, + b"nintendo.com", + 10 + ); + // Add all 10 tokens to creator's own account + MultiTokenBalance::add_to_gallery(creator_addr, token1); + + // Assert creator has the right number of tokens and supply is 10. + assert!(MultiTokenBalance::has_token(creator_addr, &token1_id), EMINT_FAILED); + assert!(MultiTokenBalance::get_token_balance(creator_addr, &token1_id) == 10, EMINT_FAILED); + assert!(MultiToken::supply(&token1_id) == 10, EMINT_FAILED); + + let token2 = MultiToken::create( + &creator, + Game { name: b"ChromeDino", edition: 2015 }, + b"google.com", + 233 + ); + MultiTokenBalance::add_to_gallery(creator_addr, token2); + assert!(MultiTokenBalance::has_token(creator_addr, &token2_id), EMINT_FAILED); + assert!(MultiTokenBalance::get_token_balance(creator_addr, &token2_id) == 233, EMINT_FAILED); + + + + /* + =============================================================== + Test transferring tokens without splitting of tokens + =============================================================== + */ + + // Transfer 6 units of token1 from creator to user + MultiTokenBalance::transfer_multi_token_between_galleries( + creator, // from + user_addr, // to + 6, // amount + creator_addr, // token.id.addr + 0, // token.id.creation_num + ); + + assert!(MultiTokenBalance::has_token(creator_addr, &token1_id), ETRANSFER_FAILED); + assert!(MultiTokenBalance::get_token_balance(creator_addr, &token1_id) == 4, ETRANSFER_FAILED); + assert!(MultiTokenBalance::has_token(user_addr, &token1_id), ETRANSFER_FAILED); + assert!(MultiTokenBalance::get_token_balance(user_addr, &token1_id) == 6, ETRANSFER_FAILED); + assert!(MultiToken::supply(&token1_id) == 10, ETRANSFER_FAILED); // supply should not change + + + /* + =============================================================== + Test transferring tokens with splitting of tokens + =============================================================== + */ + + // Transfer all 6 units of token1 from user to creator + MultiTokenBalance::transfer_multi_token_between_galleries( + user, creator_addr, 6, creator_addr, 0, + ); + assert!(!MultiTokenBalance::has_token(user_addr, &token1_id), ETRANSFER_FAILED); // user doesn't have token1 anymore + assert!(MultiTokenBalance::get_token_balance(user_addr, &token1_id) == 0, ETRANSFER_FAILED); + assert!(MultiTokenBalance::has_token(creator_addr, &token1_id), ETRANSFER_FAILED); + assert!(MultiTokenBalance::get_token_balance(creator_addr, &token1_id) == 10, ETRANSFER_FAILED); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/NFTTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/NFTTests.move new file mode 100644 index 000000000..12052f430 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/NFTTests.move @@ -0,0 +1,205 @@ +#[test_only] +module 0x1::NFTTests { + use std::guid; + use 0x1::NFT; + use 0x1::NFTGallery; + use std::option; + + /// A test token type to instantiate generic Tokens with. + struct Game has copy, store, drop { + name: vector, + edition: u64, + } + + struct Collection has copy, store, drop { + name: vector, + } + + struct Pokemon has copy, store, drop { + name: vector, + type: vector, + } + + const EMINT_FAILED: u64 = 0; + const ETRANSFER_FAILED: u64 = 1; + const ECOLLECTION_FAILED: u64 = 2; + + #[test(admin=@0xa550c18, creator=@0x42, user=@0x43)] + public entry fun test_all(admin: signer, creator: signer, user: signer) { + /* + =============================================================== + Initialization + preparation + =============================================================== + */ + + let creator_addr = @0x42; + let user_addr = @0x43; + + NFT::nft_initialize(admin); + NFTGallery::publish_gallery(&creator); + NFTGallery::publish_gallery(&creator); + NFTGallery::publish_gallery(&creator); + NFTGallery::publish_gallery(&user); + + let token1_id = guid::create_id(creator_addr, 0); + let token2_id = guid::create_id(creator_addr, 1); + + /* + =============================================================== + Test minting + =============================================================== + */ + + let token1 = NFT::create( + &creator, + Game { name: b"Mario", edition: 2008 }, + b"nintendo.com", + 10, + option::none(), + ); + assert!(NFT::get_balance(&token1) == 10, EMINT_FAILED); + assert!(NFT::get_supply(&token1) == 10, EMINT_FAILED); + assert!(NFT::get_content_uri(&token1) == b"nintendo.com", EMINT_FAILED); + assert!(NFT::get_metadata(&token1) == Game { name: b"Mario", edition: 2008, }, EMINT_FAILED); + assert!(NFT::get_parent_id(&token1) == option::none(), EMINT_FAILED); + + + // Add all 10 tokens to creator's own account + NFTGallery::add_to_gallery(creator_addr, token1); + + // assert! creator has the right number of tokens and supply is 10. + assert!(NFTGallery::has_token(creator_addr, &token1_id), EMINT_FAILED); + assert!(NFTGallery::get_token_balance(creator_addr, &token1_id) == 10, EMINT_FAILED); + assert!(NFTGallery::get_token_balance(creator_addr, &token1_id) == 10, EMINT_FAILED); + + let token2 = NFT::create( + &creator, + Game { name: b"ChromeDino", edition: 2015 }, + b"google.com", + 233, + option::none(), + ); + NFTGallery::add_to_gallery(creator_addr, token2); + assert!(NFTGallery::has_token(creator_addr, &token2_id), EMINT_FAILED); + assert!(NFTGallery::get_token_balance(creator_addr, &token2_id) == 233, EMINT_FAILED); + + + + /* + =============================================================== + Test collections + =============================================================== + */ + + // Create collection first + let collection = NFT::create( + &creator, + Collection { name: b"Pokemon" }, + b"nintendo.com", + 1, + option::none(), + ); + + let pikachu = NFT::create( + &creator, + Pokemon { name: b"Pikachu", type: b"electric", }, + b"nintendo.com", + 10, + option::some(NFT::id(&collection)), + ); + let charmander = NFT::create( + &creator, + Pokemon { name: b"Charmander", type: b"fire", }, + b"nintendo.com", + 10, + option::some(NFT::id(&collection)), + ); + + let pikachu_id = NFT::id(&pikachu); + NFTGallery::add_to_gallery(creator_addr, pikachu); + assert!(NFTGallery::get_token_balance(creator_addr, &pikachu_id) == 10, ECOLLECTION_FAILED); + assert!(NFTGallery::get_token_supply(creator_addr, &pikachu_id) == 10, ECOLLECTION_FAILED); + assert!(NFTGallery::get_token_content_uri(creator_addr, &pikachu_id) == b"nintendo.com", ECOLLECTION_FAILED); + assert!(NFTGallery::get_token_metadata(creator_addr, &pikachu_id) == Pokemon { name: b"Pikachu", type: b"electric", }, ECOLLECTION_FAILED); + assert!(NFTGallery::get_token_parent_id(creator_addr, &pikachu_id) == option::some(NFT::id(&collection)), ECOLLECTION_FAILED); + + NFTGallery::add_to_gallery(creator_addr, charmander); + NFTGallery::add_to_gallery(creator_addr, collection); + + /* + =============================================================== + Test transferring tokens without splitting of tokens + =============================================================== + */ + + // Transfer 6 units of token1 from creator to user + NFTGallery::transfer_token_between_galleries_impl( + &creator, // from + user_addr, // to + 6, // amount + creator_addr, // token.id.addr + 0, // token.id.creation_num + ); + + assert!(NFTGallery::has_token(creator_addr, &token1_id), ETRANSFER_FAILED); + assert!(NFTGallery::get_token_balance(creator_addr, &token1_id) == 4, ETRANSFER_FAILED); + assert!(NFTGallery::has_token(user_addr, &token1_id), ETRANSFER_FAILED); + assert!(NFTGallery::get_token_balance(user_addr, &token1_id) == 6, ETRANSFER_FAILED); + assert!(NFTGallery::get_token_supply(user_addr, &token1_id) == 10, ETRANSFER_FAILED); // supply should not change + + + /* + =============================================================== + Test transferring tokens with splitting of tokens + =============================================================== + */ + + // Transfer all 6 units of token1 from user to creator + NFTGallery::transfer_token_between_galleries_impl( + &user, creator_addr, 6, creator_addr, 0, + ); + assert!(!NFTGallery::has_token(user_addr, &token1_id), ETRANSFER_FAILED); // user doesn't have token1 anymore + assert!(NFTGallery::get_token_balance(user_addr, &token1_id) == 0, ETRANSFER_FAILED); + assert!(NFTGallery::has_token(creator_addr, &token1_id), ETRANSFER_FAILED); + assert!(NFTGallery::get_token_balance(creator_addr, &token1_id) == 10, ETRANSFER_FAILED); + + /* + =============================================================== + Test tokens with inline data + =============================================================== + */ + let nft = NFT::create( + &creator, + Game { name: b"Mario", edition: 2008 }, + b"nintendo.com", + 1, + option::none(), + ); + assert!(NFT::is_data_inlined(&nft), EMINT_FAILED); + assert!(NFT::get_balance(&nft) == 1, EMINT_FAILED); + assert!(NFT::get_supply(&nft) == 1, EMINT_FAILED); + assert!(NFT::get_content_uri(&nft) == b"nintendo.com", EMINT_FAILED); + assert!(NFT::get_metadata(&nft) == Game { name: b"Mario", edition: 2008, }, EMINT_FAILED); + assert!(NFT::get_parent_id(&nft) == option::none(), EMINT_FAILED); + + let nft_id = NFT::id(&nft); + let nft_creator_addr = guid::id_creator_address(&nft_id); + let nft_creation_num = guid::id_creation_num(&nft_id); + NFTGallery::add_to_gallery(creator_addr, nft); + assert!(NFTGallery::has_token(creator_addr, &nft_id), EMINT_FAILED); + + + NFTGallery::transfer_token_between_galleries_impl( + &creator, // from + user_addr, // to + 1, // amount + nft_creator_addr, // token.id.addr + nft_creation_num, // token.id.creation_num + ); + assert!(!NFTGallery::has_token(creator_addr, &nft_id), ETRANSFER_FAILED); + assert!(NFTGallery::has_token(user_addr, &nft_id), ETRANSFER_FAILED); + assert!(NFTGallery::get_token_balance(user_addr, &nft_id) == 1, ETRANSFER_FAILED); + assert!(NFTGallery::get_token_supply(user_addr, &nft_id) == 1, ETRANSFER_FAILED); + assert!(NFTGallery::get_token_metadata(user_addr, &nft_id) == Game { name: b"Mario", edition: 2008, }, ETRANSFER_FAILED); + } +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/VoteTests.move b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/VoteTests.move new file mode 100644 index 000000000..af62356ea --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/move-packages/experimental/tests/VoteTests.move @@ -0,0 +1,302 @@ +#[test_only] +module ExperimentalFramework::VoteTests { + + use std::bcs; + use std::signer; + use std::unit_test; + use std::vector; + use CoreFramework::DiemTimestamp; + use ExperimentalFramework::Genesis; + use ExperimentalFramework::Vote; + + struct TestProposal has store, copy, drop { + test_data: u8, + } + + fun get_proposer(): signer { + vector::pop_back(&mut unit_test::create_signers_for_testing(1)) + } + + fun get_three_voters(): (signer, address, signer, address, signer, address) { + let signers = &mut unit_test::create_signers_for_testing(3); + let voter1 = vector::pop_back(signers); + let voter2 = vector::pop_back(signers); + let voter3 = vector::pop_back(signers); + let voter1_address = signer::address_of(&voter1); + let voter2_address = signer::address_of(&voter2); + let voter3_address = signer::address_of(&voter3); + (voter1, voter1_address, voter2, voter2_address, voter3, voter3_address) + } + + fun vote_test_helper( + dr: &signer, + expiration_timestamp_secs: u64, + ) : (signer, signer, signer, Vote::BallotID, TestProposal) { + let (voter1, voter1_address, voter2, voter2_address, voter3, voter3_address) = get_three_voters(); + let approvers = vector::empty(); + vector::push_back(&mut approvers, Vote::new_weighted_voter(1, bcs::to_bytes(&voter1_address))); + vector::push_back(&mut approvers, Vote::new_weighted_voter(1, bcs::to_bytes(&voter2_address))); + vector::push_back(&mut approvers, Vote::new_weighted_voter(1, bcs::to_bytes(&voter3_address))); + + let (proposer, _addr, _addr_bcs) = ballot_setup(dr); + let proposal = TestProposal { + test_data: 1, + }; + let ballot_id = Vote::create_ballot( + &proposer, // ballot_account + *(&proposal), // proposal + b"test_proposal", // proposal_type + 2, // num_votes_required + approvers, // allowed_voters + expiration_timestamp_secs, // expiration_timestamp_secs + ); + (voter1, voter2, voter3, ballot_id, proposal) + } + + fun ballot_setup(dr: &signer): (signer, address, vector) { + Genesis::setup(dr); + let proposer = get_proposer(); + let addr = signer::address_of(&proposer); + let addr_bcs = bcs::to_bytes(&addr); + (proposer, addr, addr_bcs) + } + + #[test(dr = @CoreResources)] + fun create_ballot_success(dr: signer) { + let (proposer, addr, addr_bcs) = ballot_setup(&dr); + let ballot_id = Vote::create_ballot( + &proposer, + TestProposal { + test_data: 1, + }, + b"test_proposal", + 1, + vector::singleton(Vote::new_weighted_voter(1, *(&addr_bcs))), + 10, + ); + assert!(&ballot_id == &Vote::new_ballot_id(0, addr), 0); + + let ballot_id = Vote::create_ballot( + &proposer, + TestProposal { + test_data: 1, + }, + b"test_proposal", + 1, + vector::singleton(Vote::new_weighted_voter(1, *(&addr_bcs))), + 10, + ); + assert!(&ballot_id == &Vote::new_ballot_id(1, addr), 0); + + let ballot_id = Vote::create_ballot( + &proposer, + TestProposal { + test_data: 1, + }, + b"test_proposal", + 1, + vector::singleton(Vote::new_weighted_voter(1, addr_bcs)), + 10, + ); + assert!(&ballot_id == &Vote::new_ballot_id(2, addr), 0); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 263, location = Vote)] + fun create_ballot_expired_timestamp(dr: signer) { + let (proposer, _, addr_bcs) = ballot_setup(&dr); + Vote::create_ballot( + &proposer, // ballot_account + TestProposal { // proposal + test_data: 1, + }, + b"test_proposal", // proposal_type + 1, // num_votes_required + vector::singleton(Vote::new_weighted_voter(1, addr_bcs)), // allowed_voters + 0, // expiration_timestamp_secs + ); + } + + #[test(vm = @VMReserved, dr = @CoreResources)] + fun gc_internal(vm: signer, dr: signer) { + let (proposer, addr, addr_bcs) = ballot_setup(&dr); + let _ballot_id1 = Vote::create_ballot( + &proposer, + TestProposal { + test_data: 1, + }, + b"test_proposal", + 1, + vector::singleton(Vote::new_weighted_voter(1, *(&addr_bcs))), + 1, + ); + + let _ballot_id2 = Vote::create_ballot( + &proposer, + TestProposal { + test_data: 1, + }, + b"test_proposal", + 1, + vector::singleton(Vote::new_weighted_voter(1, *(&addr_bcs))), + 2, + ); + + let _ballot_id3 = Vote::create_ballot( + &proposer, + TestProposal { + test_data: 1, + }, + b"test_proposal", + 1, + vector::singleton(Vote::new_weighted_voter(1, *(&addr_bcs))), + 3, + ); + + let _ballot_id4 = Vote::create_ballot( + &proposer, + TestProposal { + test_data: 1, + }, + b"test_proposal", + 1, + vector::singleton(Vote::new_weighted_voter(1, addr_bcs)), + 4, + ); + + DiemTimestamp::update_global_time(&vm, @0xCAFE, 3000000); + let remove_ballots = Vote::gc_test_helper(addr); + assert!(vector::length(&remove_ballots) == 2, 0); + assert!(&vector::pop_back(&mut remove_ballots) == &Vote::new_ballot_id(1, addr), 0); + assert!(&vector::pop_back(&mut remove_ballots) == &Vote::new_ballot_id(0, addr), 0); + } + + // TODO: test disabled due to timeout + /* + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 520, location = Vote)] + fun create_ballots_too_many(dr: signer) { + let (proposer, _, addr_bcs) = ballot_setup(&dr); + let i = 0; + // limit is 256 + while (i <= 257) { + Vote::create_ballot( + &proposer, // ballot_account + TestProposal { // proposal + test_data: 1, + }, + b"test_proposal", // proposal_type + 1, // num_votes_required + Vector::singleton(Vote::new_weighted_voter(1, *(&addr_bcs))), // allowed_voters + 10, // expiration_timestamp_secs + ); + i = i + 1; + } + } + */ + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 769, location = Vote)] + fun remove_ballot(dr: signer) { + let (voter1, _voter2, _voter3, ballot_id, proposal) = vote_test_helper(&dr, 10); + Vote::remove_ballot_internal(get_proposer(), *(&ballot_id)); + // Vote fails because there is no ballot + Vote::vote(&voter1, *(&ballot_id), b"test_proposal", *(&proposal)); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 769, location = Vote)] + fun vote_simple(dr: signer) { + let (voter1, voter2, voter3, ballot_id, proposal) = vote_test_helper(&dr, 10); + // First vote does not approve the ballot + assert!(!Vote::vote(&voter1, *(&ballot_id), b"test_proposal", *(&proposal)), 0); + // Second vote approves the ballot + assert!(Vote::vote(&voter2, *(&ballot_id), b"test_proposal", *(&proposal)), 0); + // Third vote aborts + Vote::vote(&voter3, *(&ballot_id), b"test_proposal", *(&proposal)); + } + + #[test(dr = @CoreResources)] + fun vote_weighted(dr: signer) { + let (voter1, voter1_address, voter2, voter2_address, _voter3, voter3_address) = get_three_voters(); + let approvers = vector::empty(); + vector::push_back(&mut approvers, Vote::new_weighted_voter(3, bcs::to_bytes(&voter1_address))); + vector::push_back(&mut approvers, Vote::new_weighted_voter(4, bcs::to_bytes(&voter2_address))); + vector::push_back(&mut approvers, Vote::new_weighted_voter(2, bcs::to_bytes(&voter3_address))); + + let (proposer, _addr, _addr_bcs) = ballot_setup(&dr); + let proposal = TestProposal { + test_data: 1, + }; + let ballot_id = Vote::create_ballot( + &proposer, // ballot_account + *(&proposal), // proposal + b"test_proposal", // proposal_type + 7, // num_votes_required + approvers, // allowed_voters + 10, // expiration_timestamp_secs + ); + + + // First vote does not approve the ballot + assert!(!Vote::vote(&voter1, *(&ballot_id), b"test_proposal", *(&proposal)), 0); + // Second vote approves the ballot + assert!(Vote::vote(&voter2, *(&ballot_id), b"test_proposal", *(&proposal)), 0); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 263, location = Vote)] + fun vote_expired_ts(dr: signer) { + let (voter1, _voter2, _voter3, ballot_id, proposal) = vote_test_helper(&dr, 0); + // Ballot has expired + Vote::vote(&voter1, *(&ballot_id), b"test_proposal", *(&proposal)); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 2049, location = Vote)] + fun vote_repeat(dr: signer) { + let (voter1, _voter2, _voter3, ballot_id, proposal) = vote_test_helper(&dr, 10); + // First vote does not approve the ballot + assert!(!Vote::vote(&voter1, *(&ballot_id), b"test_proposal", *(&proposal)), 0); + // Cannot vote again + Vote::vote(&voter1, *(&ballot_id), b"test_proposal", *(&proposal)); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 1031, location = Vote)] + fun vote_invalid_proposal_type(dr: signer) { + let (voter1, _voter2, _voter3, ballot_id, proposal) = vote_test_helper(&dr, 10); + // Invalid proposal type + Vote::vote(&voter1, *(&ballot_id), b"invalid", *(&proposal)); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 1031, location = Vote)] + fun vote_invalid_proposal(dr: signer) { + let (voter1, _voter2, _voter3, ballot_id, _proposal) = vote_test_helper(&dr, 10); + let invalid_proposal = TestProposal { + test_data: 100, + }; + // Invalid proposal + Vote::vote(&voter1, *(&ballot_id), b"test_proposal", invalid_proposal); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 769, location = Vote)] + fun vote_invalid_ballotid(dr: signer) { + let proposer = get_proposer(); + let (voter1, _voter2, _voter3, _ballot_id, proposal) = vote_test_helper(&dr, 10); + let invalid_ballotid = Vote::new_ballot_id(100, signer::address_of(&proposer)); + // Invalid ballotid + Vote::vote(&voter1, invalid_ballotid, b"test_proposal", proposal); + } + + #[test(dr = @CoreResources)] + #[expected_failure(abort_code = 1281, location = Vote)] + fun vote_invalid_voter(dr: signer) { + let (_voter1, _voter2, _voter3, ballot_id, proposal) = vote_test_helper(&dr, 10); + let invalid_voter = vector::pop_back(&mut unit_test::create_signers_for_testing(4)); + Vote::vote(&invalid_voter, ballot_id, b"test_proposal", proposal); + } + +} diff --git a/vendors/move/crates/documentation/examples/diem-framework/prove_all.sh b/vendors/move/crates/documentation/examples/diem-framework/prove_all.sh new file mode 100644 index 000000000..d5ed1a864 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/prove_all.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (c) The Diem Core Contributors +# Copyright (c) The Move Contributors +# SPDX-License-Identifier: Apache-2.0 + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +cd "${SCRIPT_DIR}/move-packages/DPN" && cargo run -p df-cli -- prove && +cd "${SCRIPT_DIR}/move-packages/core" && cargo run -p df-cli -- prove && +cd "${SCRIPT_DIR}/move-packages/experimental" && cargo run -p df-cli -- prove diff --git a/vendors/move/crates/documentation/examples/diem-framework/test_all.sh b/vendors/move/crates/documentation/examples/diem-framework/test_all.sh new file mode 100644 index 000000000..d82ab2ce3 --- /dev/null +++ b/vendors/move/crates/documentation/examples/diem-framework/test_all.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (c) The Diem Core Contributors +# Copyright (c) The Move Contributors +# SPDX-License-Identifier: Apache-2.0 + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +cd "${SCRIPT_DIR}/move-packages/DPN" && cargo run -p df-cli -- test && +cd "${SCRIPT_DIR}/move-packages/core" && cargo run -p df-cli -- test && +cd "${SCRIPT_DIR}/move-packages/experimental" && cargo run -p df-cli -- test diff --git a/vendors/move/crates/documentation/examples/experimental/basic-coin/Move.toml b/vendors/move/crates/documentation/examples/experimental/basic-coin/Move.toml new file mode 100644 index 000000000..48547e2dc --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/basic-coin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +BasicCoin = "0xBC" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/examples/experimental/basic-coin/sources/BasicCoin.move b/vendors/move/crates/documentation/examples/experimental/basic-coin/sources/BasicCoin.move new file mode 100644 index 000000000..07afeca9a --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/basic-coin/sources/BasicCoin.move @@ -0,0 +1,150 @@ +/// This module defines a minimal and generic Coin and Balance. +module BasicCoin::BasicCoin { + use std::error; + use std::signer; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + const EALREADY_INITIALIZED: u64 = 3; + const EEQUAL_ADDR: u64 = 4; + + struct Coin has store { + value: u64 + } + + struct Balance has key { + coin: Coin + } + + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists>(signer::address_of(account)), error::already_exists(EALREADY_HAS_BALANCE)); + move_to(account, Balance { coin: empty_coin }); + } + + spec publish_balance { + include Schema_publish {addr: signer::address_of(account), amount: 0}; + } + + spec schema Schema_publish { + addr: address; + amount: u64; + + aborts_if exists>(addr); + + ensures exists>(addr); + let post balance_post = global>(addr).coin.value; + + ensures balance_post == amount; + } + + /// Mint `amount` tokens to `mint_addr`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the minting policy. + public fun mint(mint_addr: address, amount: u64, _witness: CoinType) acquires Balance { + // Deposit `amount` of tokens to mint_addr's balance + deposit(mint_addr, Coin { value: amount }); + } + + spec mint { + include DepositSchema {addr: mint_addr, amount}; + } + + /// Burn `amount` tokens from `burn_addr`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the burning policy. + public fun burn(burn_addr: address, amount: u64, _witness: CoinType) acquires Balance { + // Withdraw `amount` of tokens from mint_addr's balance + let Coin { value: _ } = withdraw(burn_addr, amount); + } + + spec burn { + // TBD + } + + + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global>(owner).coin.value + } + + spec balance_of { + pragma aborts_if_is_strict; + aborts_if !exists>(owner); + } + + /// Transfers `amount` of tokens from `from` to `to`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the transferring policy. + public fun transfer(from: &signer, to: address, amount: u64, _witness: CoinType) acquires Balance { + let from_addr = signer::address_of(from); + assert!(from_addr != to, EEQUAL_ADDR); + let check = withdraw(from_addr, amount); + deposit(to, check); + } + + spec transfer { + let addr_from = signer::address_of(from); + + let balance_from = global>(addr_from).coin.value; + let balance_to = global>(to).coin.value; + let post balance_from_post = global>(addr_from).coin.value; + let post balance_to_post = global>(to).coin.value; + + aborts_if !exists>(addr_from); + aborts_if !exists>(to); + aborts_if balance_from < amount; + aborts_if balance_to + amount > MAX_U64; + aborts_if addr_from == to; + + ensures balance_from_post == balance_from - amount; + ensures balance_to_post == balance_to + amount; + } + + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + spec withdraw { + let balance = global>(addr).coin.value; + + aborts_if !exists>(addr); + aborts_if balance < amount; + + let post balance_post = global>(addr).coin.value; + ensures result == Coin { value: amount }; + ensures balance_post == balance - amount; + } + + fun deposit(addr: address, check: Coin) acquires Balance{ + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } + + spec deposit { + let balance = global>(addr).coin.value; + let check_value = check.value; + + aborts_if !exists>(addr); + aborts_if balance + check_value > MAX_U64; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance + check_value; + } + + spec schema DepositSchema { + addr: address; + amount: u64; + let balance = global>(addr).coin.value; + + aborts_if !exists>(addr); + aborts_if balance + amount > MAX_U64; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance + amount; + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/coin-swap/Move.toml b/vendors/move/crates/documentation/examples/experimental/coin-swap/Move.toml new file mode 100644 index 000000000..fc9dbf64b --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/coin-swap/Move.toml @@ -0,0 +1,14 @@ +[package] +name = "CoinSwap" +version = "0.0.0" + +[addresses] +std = "0x1" +CoinSwap = "0xC5" +BasicCoin = "0xBC" +GoldCoin = "0x9C" +SilverCoin = "0x5C" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } +BasicCoin = { local = "../basic-coin"} diff --git a/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/CoinSwap.move b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/CoinSwap.move new file mode 100644 index 000000000..e97b7112a --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/CoinSwap.move @@ -0,0 +1,109 @@ +module CoinSwap::CoinSwap { + use std::signer; + use std::error; + use BasicCoin::BasicCoin; + use CoinSwap::PoolToken; + + const ECOINSWAP_ADDRESS: u64 = 0; + const EPOOL: u64 = 0; + + struct LiquidityPool has key { + coin1: u64, + coin2: u64, + share: u64, + } + + public fun create_pool( + coinswap: &signer, + requester: &signer, + coin1: u64, + coin2: u64, + share: u64, + witness1: CoinType1, + witness2: CoinType2 + ) { + // Create a pool at @CoinSwap. + // TODO: If the balance is already published, this step should be skipped rather than abort. + // TODO: Alternatively, `struct LiquidityPool` could be refactored to actually hold the coin (e.g., coin1: CoinType1). + BasicCoin::publish_balance(coinswap); + BasicCoin::publish_balance(coinswap); + assert!(signer::address_of(coinswap) == @CoinSwap, error::invalid_argument(ECOINSWAP_ADDRESS)); + assert!(!exists>(signer::address_of(coinswap)), error::already_exists(EPOOL)); + move_to(coinswap, LiquidityPool{coin1, coin2, share}); + + // Transfer the initial liquidity of CoinType1 and CoinType2 to the pool under @CoinSwap. + BasicCoin::transfer(requester, signer::address_of(coinswap), coin1, witness1); + BasicCoin::transfer(requester, signer::address_of(coinswap), coin2, witness2); + + // Mint PoolToken and deposit it in the account of requester. + PoolToken::setup_and_mint(requester, share); + } + + fun get_input_price(input_amount: u64, input_reserve: u64, output_reserve: u64): u64 { + let input_amount_with_fee = input_amount * 997; + let numerator = input_amount_with_fee * output_reserve; + let denominator = (input_reserve * 1000) + input_amount_with_fee; + numerator / denominator + } + + public fun coin1_to_coin2_swap_input( + coinswap: &signer, + requester: &signer, + coin1: u64, + witness1: CoinType1, + witness2: CoinType2 + ) acquires LiquidityPool { + assert!(signer::address_of(coinswap) == @CoinSwap, error::invalid_argument(ECOINSWAP_ADDRESS)); + assert!(exists>(signer::address_of(coinswap)), error::not_found(EPOOL)); + let pool = borrow_global_mut>(signer::address_of(coinswap)); + let coin2 = get_input_price(coin1, pool.coin1, pool.coin2); + pool.coin1 = pool.coin1 + coin1; + pool.coin2 = pool.coin2 - coin2; + + BasicCoin::transfer(requester, signer::address_of(coinswap), coin1, witness1); + BasicCoin::transfer(coinswap, signer::address_of(requester), coin2, witness2); + } + + public fun add_liquidity( + account: &signer, + coin1: u64, + coin2: u64, + witness1: CoinType1, + witness2: CoinType2, + ) acquires LiquidityPool { + let pool = borrow_global_mut>(@CoinSwap); + + let coin1_added = coin1; + let share_minted = (coin1_added * pool.share) / pool.coin1; + let coin2_added = (share_minted * pool.coin2) / pool.share; + + pool.coin1 = pool.coin1 + coin1_added; + pool.coin2 = pool.coin2 + coin2_added; + pool.share = pool.share + share_minted; + + BasicCoin::transfer(account, @CoinSwap, coin1, witness1); + BasicCoin::transfer(account, @CoinSwap, coin2, witness2); + PoolToken::mint(signer::address_of(account), share_minted) + } + + public fun remove_liquidity( + coinswap: &signer, + requester: &signer, + share: u64, + witness1: CoinType1, + witness2: CoinType2, + ) acquires LiquidityPool { + let pool = borrow_global_mut>(@CoinSwap); + + let coin1_removed = (pool.coin1 * share) / pool.share; + let coin2_removed = (pool.coin2 * share) / pool.share; + + pool.coin1 = pool.coin1 - coin1_removed; + pool.coin2 = pool.coin2 - coin2_removed; + pool.share = pool.share - share; + + BasicCoin::transfer(coinswap, signer::address_of(requester), coin1_removed, witness1); + BasicCoin::transfer(coinswap, signer::address_of(requester), coin2_removed, witness2); + PoolToken::burn(signer::address_of(requester), share) + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/GoldCoin.move b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/GoldCoin.move new file mode 100644 index 000000000..75d1a8dd2 --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/GoldCoin.move @@ -0,0 +1,15 @@ +module GoldCoin::GoldCoin { + use std::signer; + use BasicCoin::BasicCoin; + + struct GoldCoin has drop {} + + public fun setup_and_mint(account: &signer, amount: u64) { + BasicCoin::publish_balance(account); + BasicCoin::mint(signer::address_of(account), amount, GoldCoin{}); + } + + public fun transfer(from: &signer, to: address, amount: u64) { + BasicCoin::transfer(from, to, amount, GoldCoin {}); + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/PoolToken.move b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/PoolToken.move new file mode 100644 index 000000000..827b0b699 --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/PoolToken.move @@ -0,0 +1,25 @@ +module CoinSwap::PoolToken { + use std::signer; + use BasicCoin::BasicCoin; + + struct PoolToken has drop {} + + public fun setup_and_mint(account: &signer, amount: u64) { + BasicCoin::publish_balance>(account); + BasicCoin::mint>(signer::address_of(account), amount, PoolToken {}); + } + + public fun transfer(from: &signer, to: address, amount: u64) { + BasicCoin::transfer>(from, to, amount, PoolToken {}); + } + + public fun mint(mint_addr: address, amount: u64) { + // Deposit `total_value` amount of tokens to mint_addr's balance + BasicCoin::mint(mint_addr, amount, PoolToken {}); + } + + public fun burn(burn_addr: address, amount: u64) { + // Deposit `total_value` amount of tokens to mint_addr's balance + BasicCoin::burn(burn_addr, amount, PoolToken {}); + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/SilverCoin.move b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/SilverCoin.move new file mode 100644 index 000000000..d0b276cba --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/coin-swap/sources/SilverCoin.move @@ -0,0 +1,15 @@ +module SilverCoin::SilverCoin { + use std::signer; + use BasicCoin::BasicCoin; + + struct SilverCoin has drop {} + + public fun setup_and_mint(account: &signer, amount: u64) { + BasicCoin::publish_balance(account); + BasicCoin::mint(signer::address_of(account), amount, SilverCoin {}); + } + + public fun transfer(from: &signer, to: address, amount: u64) { + BasicCoin::transfer(from, to, amount, SilverCoin {}); + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/math-puzzle/Move.toml b/vendors/move/crates/documentation/examples/experimental/math-puzzle/Move.toml new file mode 100644 index 000000000..981ea2118 --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/math-puzzle/Move.toml @@ -0,0 +1,3 @@ +[package] +name = "math-puzzle" +version = "0.0.0" diff --git a/vendors/move/crates/documentation/examples/experimental/math-puzzle/README.md b/vendors/move/crates/documentation/examples/experimental/math-puzzle/README.md new file mode 100644 index 000000000..a27261429 --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/math-puzzle/README.md @@ -0,0 +1,63 @@ +# Math Puzzle + +This package contains an example that solves a math puzzle using Move Prover. + +## Puzzle description + +``` +Find a,b,...,h such that: + +1 <= a,b,...,h <= 9 + + a b c + + d e + ------- + f g h + +a is the double of c +b is less than h +c is equal to e +d is equal to f +e is less than or equal to 3 +f is odd +g is even +h is greater than or equal to 5 +``` + +## Solving the puzzle using Move Prover + +In `sources/puzzlie.move`, the function `Puzzle::puzzle` is constructed to take 8 numbers (i.e., `a`, `b`, ..., `h`) and abort if the input does not satisfy any rule of the puzzle. In addition, the spec block for the function is added to assert that the function always aborts, in other words, there is no input that satisfies all the rule. The Move Prover will disprove the function specification giving a counter-example which satisfies all of the puzzle rules. It will become the solution of the puzzle. + +Use the following command to run Move Prover: +``` +move prove +``` + +The following is the expected output of Move Prover: +``` + error: function does not abort under this condition + |- /Users/jkpark/puzzle.move:53:9 + | + 36 | aborts_if true; + | ^^^^^^^^^^^^^^^ + | + = at /Users/jkpark/puzzle.move:28: puzzle + = a = 6 + = b = 5 + = c = 3 + = d = 7 + = e = 3 + = f = 7 + = g = 2 + = h = 6 + ... +``` + +## Solution + +``` + a b c 6 5 3 + + d e + 7 3 + ------- ------- + f g h 7 2 6 +``` diff --git a/vendors/move/crates/documentation/examples/experimental/math-puzzle/sources/puzzle.move b/vendors/move/crates/documentation/examples/experimental/math-puzzle/sources/puzzle.move new file mode 100644 index 000000000..f2088dbd9 --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/math-puzzle/sources/puzzle.move @@ -0,0 +1,33 @@ +module 0x42::Puzzle { + fun assert0(b: bool) { + assert!(b, 0); + } + + fun puzzle(a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: u64) { + assert0(1 <= a && a <= 9); // 1 <= a <= 9 + assert0(1 <= b && b <= 9); // 1 <= b <= 9 + assert0(1 <= c && c <= 9); // 1 <= c <= 9 + assert0(1 <= d && d <= 9); // 1 <= d <= 9 + assert0(1 <= e && e <= 9); // 1 <= e <= 9 + assert0(1 <= f && f <= 9); // 1 <= f <= 9 + assert0(1 <= g && g <= 9); // 1 <= g <= 9 + assert0(1 <= h && h <= 9); // 1 <= h <= 9 + + assert0(a == c*2); // a is the double of c + assert0(b < h); // b is less than h + assert0(c == e); // c is equal to e + assert0(d == f); // d is equal to f + assert0(e <= 3); // e is less than or equal to 3 + assert0(f % 2 == 1); // f is odd + assert0(g % 2 == 0); // g is even + assert0(h >= 5); // h is greater than or equal to 5 + + assert0((c+e)%10 == h); // a b c + let carry = (c+e)/10; // + d e + assert0((b+d+carry)%10 == g); // ------- + assert0(a+(b+d+carry)/10 == f); // f g h + } + spec puzzle { + aborts_if true; // specifies that this fun always aborts. + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/rounding-error/Move.toml b/vendors/move/crates/documentation/examples/experimental/rounding-error/Move.toml new file mode 100644 index 000000000..1cb26f047 --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/rounding-error/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "RoundingError" +version = "0.0.0" + +[addresses] +std = "0x1" +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/vendors/move/crates/documentation/examples/experimental/rounding-error/sources/Reserve.move b/vendors/move/crates/documentation/examples/experimental/rounding-error/sources/Reserve.move new file mode 100644 index 000000000..aaffd36ca --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/rounding-error/sources/Reserve.move @@ -0,0 +1,89 @@ +module NamedAddr::Reserve { + use std::fixed_point32::{Self, FixedPoint32}; + + const ADMIN: address = @NamedAddr; + + struct ReserveComponent has store { + backing_value: u64, + backing_ratio: FixedPoint32, + } + + struct Coin1Info has key { + total_value: u64, + reserve_coin2: ReserveComponent, + } + + public fun mint_coin1(amount_to_mint: u64, backing_coin2: u64): u64 // returns the minted Coin1. + acquires Coin1Info { + assert!(amount_to_mint > 0, 1); + let coin1info = borrow_global_mut(ADMIN); + let coin2_amount_to_reserve = fixed_point32::multiply_u64(amount_to_mint, *& coin1info.reserve_coin2.backing_ratio) + 1; + assert!(backing_coin2 == coin2_amount_to_reserve, 2); + coin1info.reserve_coin2.backing_value = coin1info.reserve_coin2.backing_value + coin2_amount_to_reserve; + coin1info.total_value = coin1info.total_value + amount_to_mint; + amount_to_mint + } + spec mint_coin1 { + let coin1info = global(ADMIN); + let coin2_amount_to_reserve = fixed_point32::spec_multiply_u64(amount_to_mint, coin1info.reserve_coin2.backing_ratio) + 1; + aborts_if amount_to_mint == 0; + aborts_if backing_coin2 != coin2_amount_to_reserve; + aborts_if global(ADMIN).total_value + amount_to_mint > MAX_U64; + aborts_if coin1info.reserve_coin2.backing_value + backing_coin2 > MAX_U64; + aborts_if !exists(ADMIN); + + ensures global(ADMIN).total_value == old(global(ADMIN).total_value) + amount_to_mint; + ensures global(ADMIN).reserve_coin2.backing_value == old(global(ADMIN).reserve_coin2.backing_value) + backing_coin2; + ensures backing_coin2 == coin2_amount_to_reserve; + } + + public fun mint_coin1_incorrect(amount_to_mint: u64, backing_coin2: u64): u64 // returns the minted Coin1. + acquires Coin1Info { + assert!(amount_to_mint > 0, 1); + let coin1info = borrow_global_mut(ADMIN); + let coin2_amount_to_reserve = fixed_point32::multiply_u64(amount_to_mint, *& coin1info.reserve_coin2.backing_ratio); + assert!(backing_coin2 == coin2_amount_to_reserve, 2); + coin1info.reserve_coin2.backing_value = coin1info.reserve_coin2.backing_value + coin2_amount_to_reserve; + coin1info.total_value = coin1info.total_value + amount_to_mint; + amount_to_mint + } + + public fun burn_coin1(amount_to_burn: u64): u64 // returns the Coin2 that was reserved. + acquires Coin1Info { + let coin1info = borrow_global_mut(ADMIN); + let coin2_amount_to_return = fixed_point32::multiply_u64(amount_to_burn, *& coin1info.reserve_coin2.backing_ratio); + assert!(coin1info.reserve_coin2.backing_value >= coin2_amount_to_return, 1); + coin1info.reserve_coin2.backing_value = coin1info.reserve_coin2.backing_value - coin2_amount_to_return; + coin1info.total_value = coin1info.total_value - amount_to_burn; + coin2_amount_to_return + } + + public fun burn_coin1_incorrect(amount_to_burn: u64): u64 // returns the Coin2 that was reserved. + acquires Coin1Info { + let coin1info = borrow_global_mut(ADMIN); + let coin2_amount_to_return = fixed_point32::multiply_u64(amount_to_burn, *& coin1info.reserve_coin2.backing_ratio) + 1; + assert!(coin1info.reserve_coin2.backing_value >= coin2_amount_to_return, 1); + coin1info.reserve_coin2.backing_value = coin1info.reserve_coin2.backing_value - coin2_amount_to_return; + coin1info.total_value = coin1info.total_value - amount_to_burn; + coin2_amount_to_return + } + + fun mint_and_burn(amount_to_mint: u64, backing_coin2: u64): u64 acquires Coin1Info{ + let coin1 = mint_coin1(amount_to_mint, backing_coin2); + let coin2 = burn_coin1(coin1); + spec { + assert coin2 <= backing_coin2; + }; + coin2 + } + + spec module { + invariant exists(ADMIN) ==> + global(ADMIN).reserve_coin2.backing_ratio == fixed_point32::spec_create_from_rational(1, 2); + + invariant + exists(ADMIN) ==> + fixed_point32::spec_multiply_u64(global(ADMIN).total_value, global(ADMIN).reserve_coin2.backing_ratio) + <= global(ADMIN).reserve_coin2.backing_value; + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/rounding-error/sources/Uniswap.move b/vendors/move/crates/documentation/examples/experimental/rounding-error/sources/Uniswap.move new file mode 100644 index 000000000..1f24eb5ee --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/rounding-error/sources/Uniswap.move @@ -0,0 +1,130 @@ +module NamedAddr::Uniswap { + + const PoolAddr: address = @NamedAddr; + + struct Pool has key { + coin1: u64, + coin2: u64, + total_share: u64 + } + + fun getInputPrice(input_amount: u64, input_reserve: u64, output_reserve: u64): u64 { + let input_amount_with_fee = input_amount * 997; + let numerator = input_amount_with_fee * output_reserve; + let denominator = (input_reserve * 1000) + input_amount_with_fee; + numerator / denominator + } + public fun coin1_to_coin2_swap_code(coin1_in: u64): u64 acquires Pool { + let pool = borrow_global_mut(PoolAddr); + let coin2_out = getInputPrice(coin1_in, pool.coin1, pool.coin2); + pool.coin1 = pool.coin1 + coin1_in; + pool.coin2 = pool.coin2 - coin2_out; + coin2_out + } + spec coin1_to_coin2_swap_code { + let old_pool = global(PoolAddr); + let post new_pool = global(PoolAddr); + ensures old_pool.coin1 * old_pool.coin2 <= new_pool.coin1 * new_pool.coin2; // safety property + } + + // https://hackmd.io/@HaydenAdams/HJ9jLsfTz?type=view#ETH-%E2%87%84-ERC20-Trades + public fun coin1_to_coin2_swap_whitepaper(coin1_in: u64): u64 acquires Pool { + assert! (coin1_in > 0, 1); + let fee = coin1_in * 3 / 1000; // 0.3% + let pool = borrow_global_mut(PoolAddr); + spec { + assume pool.coin1 > 0; + assume pool.coin2 > 0; + assume pool.coin1 == 1337; + assume pool.coin2 == 252; + }; + let inv = pool.coin1 * pool.coin2; // `inv` may need to be u128 + let new_pool_coin1 = pool.coin1 + coin1_in; + let new_pool_coin2 = inv / (new_pool_coin1 - fee); // No div-by-zero because (new_pool_coin1 - fee) cannot be 0. + let coin2_out = pool.coin2 - new_pool_coin2; + pool.coin1 = new_pool_coin1; + pool.coin2 = new_pool_coin2; + coin2_out + } + spec coin1_to_coin2_swap_whitepaper { + let old_pool = global(PoolAddr); + let post new_pool = global(PoolAddr); + ensures old_pool.coin1 < new_pool.coin1; + ensures old_pool.coin2 >= new_pool.coin2; + ensures old_pool.coin1 * old_pool.coin2 <= new_pool.coin1 * new_pool.coin2; + } + + public fun add_liquidity(coin1_in: u64, coin2_in: u64): u64 // returns liquidity share + acquires Pool { + let pool = borrow_global_mut(PoolAddr); + + let coin1_added = coin1_in; + let share_minted = (coin1_added * pool.total_share) / pool.coin1; + let coin2_added = (share_minted * pool.coin2) / pool.total_share; + // let coin2_added = (coin1_added * pool.coin2 ) / pool.coin1; // alternatively ... + + assert!(coin2_in == coin2_added, 1); + + pool.coin1 = pool.coin1 + coin1_added; + pool.coin2 = pool.coin2 + coin2_added; + pool.total_share = pool.total_share + share_minted; + + share_minted + } + spec add_liquidity { + let old_pool = global(PoolAddr); + let post new_pool = global(PoolAddr); + ensures old_pool.coin1 <= new_pool.coin1; + ensures old_pool.coin2 <= new_pool.coin2; + ensures old_pool.total_share <= new_pool.total_share; + ensures old_pool.coin1 * old_pool.coin2 <= new_pool.coin1 * new_pool.coin2; + } + + public fun remove_liquidity(share: u64): (u64, u64) // returns (coin1, coin2) + acquires Pool { + let pool = borrow_global_mut(PoolAddr); + + let coin1_removed = (pool.coin1 * share) / pool.total_share; + let coin2_removed = (pool.coin2 * share) / pool.total_share; + + pool.coin1 = pool.coin1 - coin1_removed; + pool.coin2 = pool.coin2 - coin2_removed; + pool.total_share = pool.total_share - share; + + (coin1_removed, coin2_removed) + } + spec remove_liquidity { + pragma verify=false; + let old_pool = global(PoolAddr); + let post new_pool = global(PoolAddr); + ensures old_pool.coin1 <= new_pool.coin1; + ensures old_pool.coin2 <= new_pool.coin2; + ensures old_pool.total_share <= new_pool.total_share; + ensures old_pool.coin1 * old_pool.coin2 <= new_pool.coin1 * new_pool.coin2; + } + + // #[test] // TODO: cannot specify the test-only functions + fun no_free_money_theorem(coin1_in: u64, coin2_in: u64): (u64, u64) acquires Pool { + let share = add_liquidity(coin1_in, coin2_in); + remove_liquidity(share) + } + spec no_free_money_theorem { + pragma verify=false; + ensures result_1 <= coin1_in; + ensures result_2 <= coin2_in; + } + + + public fun coin1_to_coin2_swap_code_simple(coin1_in: u64): u64 acquires Pool { + assert! (coin1_in > 0, 1); + let pool = borrow_global_mut(PoolAddr); + spec { + assume pool.coin1 > 0; + assume pool.coin2 > 0; + }; + let coin2_out = (997 * coin1_in * pool.coin2) / (1000 * pool.coin1 + 997 * coin1_in); + pool.coin1 = pool.coin1 + coin1_in; + pool.coin2 = pool.coin2 - coin2_out; + coin2_out + } +} diff --git a/vendors/move/crates/documentation/examples/experimental/verify-sort/Move.toml b/vendors/move/crates/documentation/examples/experimental/verify-sort/Move.toml new file mode 100644 index 000000000..1c74136db --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/verify-sort/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "Loop" +version = "0.0.0" + +[addresses] +Loop = "0x42" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/examples/experimental/verify-sort/sources/loop.move b/vendors/move/crates/documentation/examples/experimental/verify-sort/sources/loop.move new file mode 100644 index 000000000..b673830c9 --- /dev/null +++ b/vendors/move/crates/documentation/examples/experimental/verify-sort/sources/loop.move @@ -0,0 +1,66 @@ +// exclude_for: cvc5 +module 0x42::VerifySort { + + use std::vector; + // iperm is a ghost variable for verification + public fun verify_sort(v: &mut vector, iperm: &mut vector) { + let vlen = vector::length(v); + spec { + assume vlen == 42; + assume len(iperm) == vlen && (forall k in 0..vlen : iperm[k] == k); + }; + if (vlen <= 1) return (); + + let i = 0; + let j = 1; + while + ({ + spec { + // loop invariant that proves order of output vector + invariant i >= 0 && i < vlen; + invariant j >= 1 && j <= vlen; + invariant j == vlen ==> i == vlen - 1; + invariant j >= i + 1; + invariant len(v) == vlen; + invariant forall k in 0..i, l in 0..i : k < l ==> v[k] <= v[l]; + invariant forall k in 0..i, l in i..vlen : v[k] <= v[l]; + invariant forall k in (i + 1)..j : v[i] <= v[k]; + + // loop invariant that proves output vector is a permutation of input vector + invariant len(iperm) == vlen && + (forall k in 0..vlen : old(v)[iperm[k]] == v[k]) && + (forall k in 0..vlen : iperm[k] >= 0 && iperm[k] < vlen) && + (forall k in 0..vlen, l in 0..vlen : k != l ==> iperm[k] != iperm[l]); + }; + (i < vlen - 1) + }) + { + if (*vector::borrow(v, i) > *vector::borrow(v, j)) { + vector::swap(v, i, j); + vector::swap(iperm, i, j); + }; + + if (j < vlen - 1 ) { + j = j + 1; + } else { + i = i + 1; + j = i + 1; + }; + }; + spec { + assert len(v) == vlen; + assert i == vlen - 1; + assert j == vlen; + assert v[0] <= v[1]; + assert v[vlen - 2] <= v[vlen - 1]; + }; + } + spec verify_sort { + aborts_if false; + ensures forall i in 0..len(v)-1: v[i] <= v[i+1]; + ensures exists perm : vector : len(perm) == len(v) && + (forall k in 0..len(v) : old(v)[perm[k]] == v[k]) && + (forall k in 0..len(v) : perm[k] >= 0 && perm[k] < len(v)) && + (forall k in 0..len(v), l in 0..len(v) : k != l ==> perm[k] != perm[l]); + } +} diff --git a/vendors/move/crates/documentation/spec/vm.md b/vendors/move/crates/documentation/spec/vm.md new file mode 100644 index 000000000..fea24adb6 --- /dev/null +++ b/vendors/move/crates/documentation/spec/vm.md @@ -0,0 +1,649 @@ +# Move VM Specification + +Instantiation of a Move VM just initializes an instance of a `Loader`, that +is, a small set of empty tables (few instances of `HashMap` and `Vec` behind +`Mutex`). Initialization of a VM is reasonably inexpensive. The `Loader` is +effectively the code cache. The code cache has the lifetime of the VM. Code +is loaded at runtime when functions and scripts are executed. Once loaded, +modules and scripts are reused in their loaded form and ready to be executed +immediately. Loading code is expensive and the VM performs eager +loading. When execution starts, no more loading takes place, all code through +any possible control flow is ready to be executed and cached at load time. +Maybe, more importantly, the eager model guarantees that no runtime errors can +come from linking at runtime, and that a given invocation will not fail +loading/linking because of different code paths. The consistency of the +invocation is guaranteed before execution starts. Obviously runtime errors are +still possible and "expected". + +This model fits typical blockchain requirements well: + +* Validation uses only few functions published at genesis. Once loaded, code is +always fetched from the cache and immediately available. + +* Execution is in the context of a given data view, a stable and immutable +view. As such code is stable too, and it is important to optimize the process +of loading. Also, transactions are reasonably homogeneous and reuse of code +leads to significant improvements in performance and stability. + +The VM has an internal implementation for a data cache that relieves the client from an +important responsibility (data cache consistency). That abstraction is behind +a `Session` which is the only way to talk to the runtime. + +The objective of a `Session` is to create and manage the data cache for a set +of invocations into the VM. It is also intended to return side effects in a +format that is suitable to the adapter. +A `Session` forwards calls to the `Runtime` which is where the logic and +implementation of the VM lives and starts. + +### Code Cache + +When loading a Module for the first time, the VM queries the data store for +the Module. That binary is deserialized, verified, loaded and cached by the +loader. Once loaded, a Module is never requested again for the lifetime of +that VM instance. Code is an immutable resource in the system. + +The process of loading can be summarized through the following steps: + +1. a binary—Module in a serialized form, `Vec`—is fetched from the data store. +This may require a network access +2. the binary is deserialized and verified +3. dependencies of the module are loaded (repeat 1.–4. for each dependency) +4. the module is linked to its dependencies (transformed in a representation +suitable for runtime) and cached by the loader. + +So a reference to a loaded module does not perform any fetching from the +network, or verification, or transformations into runtime structures +(e.g. linking). + +In a typical client, consistency of the code cache can be broken by a system transaction +that performs a hard upgrade, requiring the adapter to stop processing +transactions until a restart takes place. Other clients may have different +"code models" (e.g. some form of versioning). + +Overall, a client holding an instance of a Move VM has to be aware of the +behavior of the code cache and provide data views (`DataStore`) that are +compatible with the loaded code. Moreover, a client is responsible to release +and instantiate a new VM when specific conditions may alter the consistency of +the code cache. + +### Publishing + +Clients may publish modules in the system by calling: + +```rust +pub fn publish_module( + &mut self, + module: Vec, + sender: AccountAddress, + gas_status: &mut impl GasMeter, +) -> VMResult<()>; +``` + +The `module` is in a [serialized form](#Binary-Format) and the VM performs the +following steps: + +* Deserialize the module: If the module does not deserialize, an error is +returned with a proper `StatusCode`. + +* Check that the module address and the `sender` address are the same: This +check verifies that the publisher is the account that will eventually [hold +the module](#References-to-Data-and-Code). If the two addresses do not match, an +error with `StatusCode::MODULE_ADDRESS_DOES_NOT_MATCH_SENDER` is returned. + +* Check that the module is not already published: Code is immutable in +Move. An attempt to overwrite an existing module results in an error with +`StatusCode::DUPLICATE_MODULE_NAME`. + +* Verify loading: The VM performs [verification](#Verification) of the +module to prove correctness. However, neither the module nor any of its +dependencies are actually saved in the cache. The VM ensures that the module +will be loadable when a reference will be found. If a module would fail to +load an error with proper `StatusCode` is returned. + +* Publish: The VM writes the serialized bytes of the module +with the [proper key](#References-to-Data-and-Code) to the storage. +After this step any reference to the +module is valid. + +## Script Execution + +The VM allows the execution of [scripts](#Binary-Format). A script is a +Move function declared in a `script` block that performs +calls into a Framework published on-chain to accomplish a +logical transaction. A script is not saved in storage and +it cannot be invoked by other scripts or modules. + +```rust +pub fn execute_script( + &mut self, + script: Vec, + ty_args: Vec, + args: Vec>, + senders: Vec, + gas_status: &mut impl GasMeter, +) -> VMResult<()>; +``` + +The `script` is specified in a [serialized form](#Binary-Format). +If the script is generic, the `ty_args` vector contains the `TypeTag` +values for the type arguments. The `signer` account addresses for the +script are specified in the `senders` vector. Any additional arguments +are provided in the `args` vector, where each argument is a BCS-serialized +vector of bytes. The VM +performs the following steps: + +* Load the Script and the main function: + + - The `sha3_256` hash value of the `script` binary is computed. + - The hash is used to access the script cache to see if the script was + loaded. The hash is used for script identity. + - If not in the cache the script is [loaded](#Loading). If loading fails, + execution stops and an error with a proper `StatusCode` is returned. + - The script main function is [checked against the + type argument instantiation](#Verification) and if there are + errors, execution stops and the error returned. + +* Build the argument list: The first arguments are `Signer` values created by +the VM for the account addresses in the `senders` vector. Any other arguments +from the `args` vector are then checked against a whitelisted set of permitted +types and added to the arguments for the script. +The VM returns an error with `StatusCode::TYPE_MISMATCH` if +any of the types is not permitted. + +* Execute the script: The VM invokes the interpreter to [execute the +script](#Interpreter). Any error during execution is returned, and the +transaction aborted. The VM returns whether execution succeeded or +failed. + +## Script Function Execution + +Script functions (in version 2 and later of the Move VM) are similar to scripts +except that the Move bytecode comes from a Move function with `script` visibility +in an on-chain module. The script function is specified by the module and function +name: + +```rust +pub fn execute_script_function( + &mut self, + module: &ModuleId, + function_name: &IdentStr, + ty_args: Vec, + args: Vec>, + senders: Vec, + gas_status: &mut impl GasMeter, +) -> VMResult<()>; +``` + +Execution of script functions is similar to scripts. Instead of using the Move bytecodes +from a script, the script function is loaded from the on-chain module, and the Move VM +checks that it has `script` visibility. The rest of the script function execution is +the same as for scripts. If the function does not exist, execution fails with a +`FUNCTION_RESOLUTION_FAILURE` status code. If the function does not have `script` visibility, +it will fail with the `EXECUTE_SCRIPT_FUNCTION_CALLED_ON_NON_SCRIPT_VISIBLE` status code. + +## Function Execution + +The VM allows the execution of [any function in a module](#Binary-Format) +through a `ModuleId` and a function name. Function names are unique within a +module (no overloading), so the signature of the function is not +required. Argument checking is done by the [interpreter](#Interpreter). + +The adapter uses this entry point to run specific system functions as +described in [validation](#Validation) and [execution](#Execution). This is a +very powerful entry point into the system given there are no visibility +checks. Clients would likely use this entry point internally (e.g., for +constructing a genesis state), or wrap and expose it with restrictions. + +```rust +pub fn execute_function( + &mut self, + module: &ModuleId, + function_name: &IdentStr, + ty_args: Vec, + args: Vec>, + gas_status: &mut impl GasMeter, +) -> VMResult<()>; +``` + +The VM performs the following steps: + +* Load the function: + + - The specified `module` is first [loaded](#Loading). + An error in loading halts execution and returns the error with a proper + `StatusCode`. + - The VM looks up the function in the module. Failure to resolve the + function returns an error with a proper `StatusCode`. + - Every type in the `ty_args` vector is [loaded](#Loading). An error + in loading halts execution and returns the error with a proper `StatusCode`. + Type arguments are checked against type parameters and an error returned + if there is a mismatch (i.e., argument inconsistent with generic declaration). + +* Build the argument list: Arguments are checked against a whitelisted set +of permitted types (_specify which types_). The VM returns an error with +`StatusCode::TYPE_MISMATCH` if any of the types is not permitted. + +* Execute the function: The VM invokes the interpreter to [execute the +function](#Interpreter). Any error during execution aborts the interpreter +and returns the error. The VM returns whether execution succeeded or +failed. + +## Binary Format + +Modules and Scripts can only enter the VM in binary form, and Modules are +saved on chain in binary form. A Module is logically a collection of +functions and data structures. A Script is just an entry point, a single +function with arguments and no return value. + +Modules can be thought as library or shared code, whereas Scripts can only +come in input with the Transaction. + +Binaries are composed of headers and a set of tables. Some of +those tables are common to both Modules and Scripts, others specific to one or +the other. There is also data specific only to Modules or Scripts. + +The binary format makes a heavy use of +[ULEB128](https://en.wikipedia.org/wiki/LEB128) to compress integers. Most of +the data in a binary is in the form of indices, and as such compression offers +an important saving. Integers, when used with no compression are in +[little-endian](https://en.wikipedia.org/wiki/Endianness) form. + +Vectors are serialized with the size first, in ULEB128 form, followed by the +elements contiguously. + +### Binary Header + +Every binary starts with a header that has the following format: + +* `Magic`: 4 bytes 0xA1, 0x1C, 0xEB, 0x0B (aka "A11CEB0B" or "AliceBob") +* `Version`: 4 byte little-endian unsigned integer +* `Table count`: number of tables in ULEB128 form. The current maximum number +of tables is contained in 1 byte, so this is effectively the count of tables in +one byte. Not all tables need to be present. Each kind of table can only be +present once; table repetitions are not allowed. Tables can be serialized in any +order. + +### Table Headers + +Following the binary header are the table headers. There are as many tables as +defined in "table count". Each table header +has the following format: + +* `Table Kind`: 1 byte for the [kind of table](#Tables) that is serialized at +the location defined by the next 2 entries +* `Table Offset`: ULEB128 offset from the end of the table headers where the +table content starts +* `Table Length`: ULEB128 byte count of the table content + +Tables must be contiguous to each other, starting from the end of the table +headers. There must not be any gap between the content of the tables. Table +content must not overlap. + +### Tables + +A `Table Kind` is 1 byte, and it is one of: + +* `0x1`: `MODULE_HANDLES` - for both Modules and Scripts +* `0x2`: `STRUCT_HANDLES` - for both Modules and Scripts +* `0x3`: `FUNCTION_HANDLES` - for both Modules and Scriptss +* `0x4`: `FUNCTION_INSTANTIATIONS` - for both Modules and Scripts +* `0x5`: `SIGNATURES` - for both Modules and Scripts +* `0x6`: `CONSTANT_POOL` - for both Modules and Scripts +* `0x7`: `IDENTIFIERS` - for both Modules and Scripts +* `0x8`: `ADDRESS_IDENTIFIERS` - for both Modules and Scripts +* `0xA`: `STRUCT_DEFINITIONS` - only for Modules +* `0xB`: `STRUCT_DEF_INSTANTIATIONS` - only for Modules +* `0xC`: `FUNCTION_DEFINITIONS` - only for Modules +* `0xD`: `FIELD_HANDLES` - only for Modules +* `0xE`: `FIELD_INSTANTIATIONS` - only for Modules +* `0xF`: `FRIEND_DECLS` - only for Modules, version 2 and later + +The formats of the tables are: + +* `MODULE_HANDLES`: A `Module Handle` is a pair of indices that identify +the location of a module: + + * `address`: ULEB128 index into the `ADDRESS_IDENTIFIERS` table of + the account under which the module is published + * `name`: ULEB128 index into the `IDENTIFIERS` table of the name of the module + +* `STRUCT_HANDLES`: A `Struct Handle` contains all the information to +uniquely identify a user type: + + * `module`: ULEB128 index in the `MODULE_HANDLES` table of the module + where the struct is defined + * `name`: ULEB128 index into the `IDENTIFIERS` table of the name of the struct + * `nominal resource`: U8 bool defining whether the + struct is a resource (true/1) or not (false/0) + * `type parameters`: vector of [type parameter kinds](#Kinds) if the + struct is generic, an empty vector otherwise: + * `length`: ULEB128 length of the vector, effectively the number of type + parameters for the generic struct + * `kinds`: array of `length` U8 kind values; not present if length is 0 + +* `FUNCTION_HANDLES`: A `Function Handle` contains all the information to uniquely +identify a function: + + * `module`: ULEB128 index in the `MODULE_HANDLES` table of the module where + the function is defined + * `name`: ULEB128 index into the `IDENTIFIERS` table of the name of the function + * `parameters`: ULEB128 index into the `SIGNATURES` table for the argument types + of the function + * `return`: ULEB128 index into the `SIGNATURES` table for the return types of the function + * `type parameters`: vector of [type parameter kinds](#Kinds) if the function + is generic, an empty vector otherwise: + * `length`: ULEB128 length of the vector, effectively the number of type + parameters for the generic function + * `kinds`: array of `length` U8 kind values; not present if length is 0 + +* `FUNCTION_INSTANTIATIONS`: A `Function Instantiation` describes the +instantation of a generic function. Function Instantiation can be full or +partial. E.g., given a generic function `f()` a full instantiation would +be `f()` whereas a partial instantiation would be `f()` where +`Z` is a type parameter in a given context (typically another function +`g()`). + + * `function handle`: ULEB128 index into the `FUNCTION_HANDLES` table of the + generic function for this instantiation (e.g., `f()`) + * `instantiation`: ULEB128 index into the `SIGNATURES` table for the + instantiation of the function + +* `SIGNATURES`: The set of signatures in this binary. A signature is a +vector of [Signature Tokens](#SignatureTokens), so every signature will carry +the length (in ULEB128 form) followed by the Signature Tokens. + +* `CONSTANT_POOL`: The set of constants in the binary. A constant is a +copyable primitive value or a vector of vectors of primitives. Constants +cannot be user types. Constants are serialized according to the rule defined +in [Move Values](#Move-Values) and stored in the table in serialized form. A +constant in the constant pool has the following entries: + + * `type`: the [Signature Token](#SignatureTokens) (type) of the value that follows + * `length`: the length of the serialized value in bytes + * `value`: the serialized value + +* `IDENTIFIERS`: The set of identifiers in this binary. Identifiers are +vectors of chars. Their format is the length of the vector in ULEB128 form +followed by the chars. An identifier can only have characters in the ASCII set +and specifically: must start with a letter or '\_', followed by a letter, '\_' +or digit + +* `ADDRESS_IDENTIFIERS`: The set of addresses used in ModuleHandles. +Addresses are fixed size so they are stored contiguously in this table. + +* `STRUCT_DEFINITIONS`: The structs or user types defined in the binary. A +struct definition contains the following fields: + + * `struct_handle`: ULEB128 index in the `STRUCT_HANDLES` table for the + handle of this definition + * `field_information`: Field Information provides information about the + fields of the struct or whether the struct is native + + * `tag`: 1 byte, either `0x1` if the struct is native, or `0x2` if the struct + contains fields, in which case it is followed by: + * `field count`: ULEB128 number of fields for this struct + * `fields`: a field count of + + * `name`: ULEB128 index in the `IDENTIFIERS` table containing the + name of the field + * `field type`: [SignatureToken](#SignatureTokens) - the type of + the field + +* `STRUCT_DEF_INSTANTIATIONS`: the set of instantiation for any given +generic struct. It contains the following fields: + + * `struct handle`: ULEB128 index into the `STRUCT_HANDLES` table of the + generic struct for this instantiation (e.g., `struct X`) + * `instantiation`: ULEB128 index into the `SIGNATURES` table for the + instantiation of the struct. The instantiation can be either partial or complete + (e.g., `X` or `X` when inside another generic function or generic struct + with type parameter `Z`) + +* `FUNCTION_DEFINITIONS`: the set of functions defined in this binary. A +function definition contains the following fields: + + * `function_handle`: ULEB128 index in the `FUNCTION_HANDLES` table for + the handle of this definition + * `visibility`: 1 byte for the function visibility (only used in version 2 and later) + + * `0x0` if the function is private to the Module + * `0x1` if the function is public and thus visible outside this module + * `0x2` for a `script` function + * `0x3` if the function is private but also visible to `friend` modules + + * `flags`: 1 byte: + + * `0x0` if the function is private to the Module (version 1 only) + * `0x1` if the function is public and thus visible outside this module (version 1 only) + * `0x2` if the function is native, not implemented in Move + + * `acquires_global_resources`: resources accessed by this function + + * `length`: ULEB128 length of the vector, number of resources + acquired by this function + * `resources`: array of `length` ULEB128 indices into the `STRUCT_DEFS` table, + for the resources acquired by this function + + * `code_unit`: if the function is not native, the code unit follows: + + * `locals`: ULEB128 index into the `SIGNATURES` table for the types + of the locals of the function + * `code`: vector of [Bytecodes](#Bytecodes), the body of this function + + * `length`: the count of bytecodes the follows + * `bytecodes`: Bytecodes, they are variable size + +* `FIELD_HANDLES`: the set of fields accessed in code. A field handle is +composed by the following fields: + + * `owner`: ULEB128 index into the `STRUCT_DEFS` table of the type that owns the field + * `index`: ULEB128 position of the field in the vector of fields of the `owner` + +* `FIELD_INSTANTIATIONS`: the set of generic fields accessed in code. A +field instantiation is a pair of indices: + + * `field_handle`: ULEB128 index into the `FIELD_HANDLES` table for the generic field + * `instantiation`: ULEB128 index into the `SIGNATURES` table for the instantiation of + the type that owns the field + +* `FRIEND_DECLS`: the set of declared friend modules with the following for each one: + + * `address`: ULEB128 index into the `ADDRESS_IDENTIFIERS` table of + the account under which the module is published + * `name`: ULEB128 index into the `IDENTIFIERS` table of the name of the module + +### Kinds + +A `Type Parameter Kind` is 1 byte, and it is one of: + +* `0x1`: `ALL` - the type parameter can be substituted by either a resource, or a copyable type +* `0x2`: `COPYABLE` - the type parameter must be substituted by a copyable type +* `0x3`: `RESOURCE` - the type parameter must be substituted by a resource type + +### SignatureTokens + +A `SignatureToken` is 1 byte, and it is one of: + +* `0x1`: `BOOL` - a boolean +* `0x2`: `U8` - a U8 (byte) +* `0x3`: `U64` - a 64-bit unsigned integer +* `0x4`: `U128` - a 128-bit unsigned integer +* `0x5`: `ADDRESS` - an `AccountAddress` in the chain, may be a 16, 20, or 32 byte value +* `0x6`: `REFERENCE` - a reference; must be followed by another SignatureToken +representing the type referenced +* `0x7`: `MUTABLE_REFERENCE` - a mutable reference; must be followed by another +SignatureToken representing the type referenced +* `0x8`: `STRUCT` - a structure; must be followed by the index into the +`STRUCT_HANDLES` table describing the type. That index is in ULEB128 form +* `0x9`: `TYPE_PARAMETER` - a type parameter of a generic struct or a generic +function; must be followed by the index into the type parameters vector of its container. +The index is in ULEB128 form +* `0xA`: `VECTOR` - a vector - must be followed by another SignatureToken +representing the type of the vector +* `0xB`: `STRUCT_INST` - a struct instantiation; must be followed by an index +into the `STRUCT_HANDLES` table for the generic type of the instantiation, and a +vector describing the substitution types, that is, a vector of SignatureTokens +* `0xC`: `SIGNER` - a signer type, which is a special type for the VM +representing the "entity" that signed the transaction. Signer is a resource type +* `0xD`: `U16` - a 16-bit unsigned integer +* `0xE`: `U32` - a 32-bit unsigned integer +* `0xF`: `U256` - a 256-bit unsigned integer + +Signature tokens examples: + +* `u8, u128` -> `0x2 0x2 0x4` - size(`0x2`), U8(`0x2`), u128(`0x4`) +* `u8, u128, A` where A is a struct -> `0x3 0x2 0x4 0x8 0x10` - size(`0x3`), +U8(`0x2`), u128(`0x4`), Struct::A +(`0x8 0x10` assuming the struct is in the `STRUCT_HANDLES` table at position `0x10`) +* `vector
, &A` where A is a struct -> `0x2 0xA 0x5 0x8 0x10` - size(`0x2`), +vector
(`0xA 0x5`), &Struct::A +(`0x6 0x8 0x10` assuming the struct is in the `STRUCT_HANDLES` table at position `0x10`) +* `vector, &A` where A and B are a struct -> +`0x2 0xA 0x8 0x10 0x6 0xB 0x10 0x1 0x8 0x11` - +size(`0x2`), vector\(`0xA 0x8 0x10`), +&Struct::A\ (`0x6` &, `0xB 0x10` A<\_>, `0x1 0x8 0x11` B type +instantiation; assuming the struct are in the `STRUCT_HANDLES` table at position +`0x10` and `0x11` respectively) + +### Bytecodes + +Bytecodes are variable size instructions for the Move VM. Bytecodes are +composed by opcodes (1 byte) followed by a possible payload which depends on +the specific opcode and specified in "()" below: + +* `0x01`: `POP` +* `0x02`: `RET` +* `0x03`: `BR_TRUE(offset)` - offset is in ULEB128 form, and it is the target +offset in the code stream from the beginning of the code stream +* `0x04`: `BR_FALSE(offset)` - offset is in ULEB128 form, and it is the +target offset in the code stream from the beginning of the code stream +* `0x05`: `BRANCH(offset)` - offset is in ULEB128 form, and it is the target +offset in the code stream from the beginning of the code stream +* `0x06`: `LD_U64(value)` - value is a U64 in little-endian form +* `0x07`: `LD_CONST(index)` - index is in ULEB128 form, and it is an index +in the `CONSTANT_POOL` table +* `0x08`: `LD_TRUE` +* `0x09`: `LD_FALSE` +* `0x0A`: `COPY_LOC(index)` - index is in ULEB128 form, and it is an index +referring to either an argument or a local of the function. From a bytecode +perspective arguments and locals lengths are added and the index must be in that +range. If index is less than the length of arguments it refers to one of the +arguments otherwise it refers to one of the locals +* `0x0B`: `MOVE_LOC(index)` - index is in ULEB128 form, and it is an index +referring to either an argument or a local of the function. From a bytecode +perspective arguments and locals lengths are added and the index must be in that +range. If index is less than the length of arguments it refers to one of the +arguments otherwise it refers to one of the locals +* `0x0C`: `ST_LOC(index)` - index is in ULEB128 form, and it is an index +referring to either an argument or a local of the function. From a bytecode +perspective arguments and locals lengths are added and the index must be in that +range. If index is less than the length of arguments it refers to one of the +arguments otherwise it refers to one of the locals +* `0x0D`: `MUT_BORROW_LOC(index)` - index is in ULEB128 form, and it is an +index referring to either an argument or a local of the function. From a +bytecode perspective arguments and locals lengths are added and the index must +be in that range. If index is less than the length of arguments it refers to one +of the arguments otherwise it refers to one of the locals +* `0x0E`: `IMM_BORROW_LOC(index)` - index is in ULEB128 form, and it is an +index referring to either an argument or a local of the function. From a +bytecode perspective arguments and locals lengths are added and the index must +be in that range. If index is less than the length of arguments it refers to one +of the arguments otherwise it refers to one of the locals +* `0x0F`: `MUT_BORROW_FIELD(index)` - index is in ULEB128 form, and it is an +index in the `FIELD_HANDLES` table +* `0x10`: `IMM_BORROW_FIELD(index)` - index is in ULEB128 form, and it is an +index in the `FIELD_HANDLES` table +* `0x11`: `CALL(index)` - index is in ULEB128 form, and it is an index in the +`FUNCTION_HANDLES` table +* `0x12`: `PACK(index)` - index is in ULEB128 form, and it is an index in the +`STRUCT_DEFINITIONS` table +* `0x13`: `UNPACK(index)` - index is in ULEB128 form, and it is an index in +the `STRUCT_DEFINITIONS` table +* `0x14`: `READ_REF` +* `0x15`: `WRITE_REF` +* `0x16`: `ADD` +* `0x17`: `SUB` +* `0x18`: `MUL` +* `0x19`: `MOD` +* `0x1A`: `DIV` +* `0x1B`: `BIT_OR` +* `0x1C`: `BIT_AND` +* `0x1D`: `XOR` +* `0x1E`: `OR` +* `0x1F`: `AND` +* `0x20`: `NOT` +* `0x21`: `EQ` +* `0x22`: `NEQ` +* `0x23`: `LT` +* `0x24`: `GT` +* `0x25`: `LE` +* `0x26`: `GE` +* `0x27`: `ABORT` +* `0x28`: `NOP` +* `0x29`: `EXISTS(index)` - index is in ULEB128 form, and it is an index in +the `STRUCT_DEFINITIONS` table +* `0x2A`: `MUT_BORROW_GLOBAL(index)` - index is in ULEB128 form, and it is +an index in the `STRUCT_DEFINITIONS` table +* `0x2B`: `IMM_BORROW_GLOBAL(index)` - index is in ULEB128 form, and it is +an index in the `STRUCT_DEFINITIONS` table +* `0x2C`: `MOVE_FROM(index)` - index is in ULEB128 form, and it is an index +in the `STRUCT_DEFINITIONS` table +* `0x2D`: `MOVE_TO(index)` - index is in ULEB128 form, and it is an index +in the `STRUCT_DEFINITIONS` table +* `0x2E`: `FREEZE_REF` +* `0x2F`: `SHL` +* `0x30`: `SHR` +* `0x31`: `LD_U8(value)` - value is a U8 +* `0x32`: `LD_U128(value)` - value is a U128 in little-endian form +* `0x33`: `CAST_U8` +* `0x34`: `CAST_U64` +* `0x35`: `CAST_U128` +* `0x36`: `MUT_BORROW_FIELD_GENERIC(index)` - index is in ULEB128 form, +and it is an index in the `FIELD_INSTANTIATIONS` table +* `0x37`: `IMM_BORROW_FIELD_GENERIC(index)` - index is in ULEB128 form, +and it is an index in the `FIELD_INSTANTIATIONS` table +* `0x38`: `CALL_GENERIC(index)` - index is in ULEB128 form, and it is an +index in the `FUNCTION_INSTANTIATIONS` table +* `0x39`: `PACK_GENERIC(index)` - index is in ULEB128 form, and it is an +index in the `STRUCT_DEF_INSTANTIATIONS` table +* `0x3A`: `UNPACK_GENERIC(index)` - index is in ULEB128 form, and it is an +index in the `STRUCT_DEF_INSTANTIATIONS` table +* `0x3B`: `EXISTS_GENERIC(index)` - index is in ULEB128 form, and it is an +index in the `STRUCT_DEF_INSTANTIATIONS` table +* `0x3C`: `MUT_BORROW_GLOBAL_GENERIC(index)` - index is in ULEB128 form, +and it is an index in the `STRUCT_DEF_INSTANTIATIONS` table +* `0x3D`: `IMM_BORROW_GLOBAL_GENERIC(index)` - index is in ULEB128 form, +and it is an index in the `STRUCT_DEF_INSTANTIATIONS` table +* `0x3E`: `MOVE_FROM_GENERIC(index)` - index is in ULEB128 form, and it +is an index in the `STRUCT_DEF_INSTANTIATIONS` table +* `0x3F`: `MOVE_TO_GENERIC(index)` - index is in ULEB128 form, and it is +an index in the `STRUCT_DEF_INSTANTIATIONS` table + +### Module Specific Data + +A binary for a Module contains an index in ULEB128 form as its last +entry. That is after all tables. That index points to the ModuleHandle table +and it is the self module. It is where the module is stored, and a +specification of which one of the Modules in the `MODULE_HANDLES` tables is the +self one. + +### Script Specific Data + +A Script does not have a `FUNCTION_DEFINITIONS` table, and the entry point is +explicitly described in the following entries, at the end of a Script +Binary, in the order below: + +* `type parameters`: if the script entry point is generic, the number and +kind of the type parameters is in this vector. + + * `length`: ULEB128 length of the vector, effectively the number of + type parameters for the generic entry point. 0 if the script is not generic + * `kinds`: array of `length` U8 [kind](#Kinds) values, not present + if length is 0 + +* `parameters`: ULEB128 index into the `SIGNATURES` table for the argument +types of the entry point + +* `code`: vector of [Bytecodes](#Bytecodes), the body of this function + * `length`: the count of bytecodes + * `bytecodes`: Bytecodes contiguously serialized, they are variable size diff --git a/vendors/move/crates/documentation/tutorial/README.md b/vendors/move/crates/documentation/tutorial/README.md new file mode 100644 index 000000000..d15fce32b --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/README.md @@ -0,0 +1,759 @@ +# Move Tutorial + +Welcome to the Move Tutorial! In this tutorial, we are going to go through some steps of developing Move code +including design, implementation, unit testing and formal verification of Move modules. + +There are nine steps in total: + +- [Step 0: Installation](#Step0) +- [Step 1: Writing my first Move module](#Step1) +- [Step 2: Adding unit tests to my first Move module](#Step2) +- [Step 3: Designing my `BasicCoin` module](#Step3) +- [Step 4: Implementing my `BasicCoin` module](#Step4) +- [Step 5: Adding and using unit tests with the `BasicCoin` module](#Step5) +- [Step 6: Making my `BasicCoin` module generic](#Step6) +- [Step 7: Use the Move prover](#Step7) +- [Step 8: Writing formal specifications for the `BasicCoin` module](#Step8) + +Each step is designed to be self-contained in the corresponding `step_x` folder. For example, if you would +like to skip the contents in step 1 through 4, feel free to jump to step 5 since all the code we have written +before step 5 will be in `step_5` folder. At the end of some steps, we also include +additional material on more advanced topics. + +Now let's get started! + +## Step 0: Installation + +If you haven't already, open your terminal and clone [the Move repository](https://github.com/move-language/move): + +```bash +git clone https://github.com/move-language/move.git +``` + +Go to the `move` directory and run the `dev_setup.sh` script: + +```bash +cd move +./scripts/dev_setup.sh -ypt +``` + +Follow the script's prompts in order to install all of Move's dependencies. + +The script adds environment variable definitions to your `~/.profile` file. +Include them by running this command: + +```bash +source ~/.profile +```` + +Next, install Move's command-line tool by running this commands: + +```bash +cargo install --path language/tools/move-cli +``` + +You can check that it is working by running the following command: + +```bash +move --help +``` + +You should see something like this along with a list and description of a +number of commands: + +``` +move-cli 0.1.0 +Diem Association +MoveCLI is the CLI that will be executed by the `move-cli` command The `cmd` argument is added here +rather than in `Move` to make it easier for other crates to extend `move-cli` + +USAGE: + move [OPTIONS] + +OPTIONS: + --abi Generate ABIs for packages +... +``` + +If you want to find what commands are available and what they do, running +a command or subcommand with the `--help` flag will print documentation. + +Before running the next steps, `cd` to the tutorial directory: +```bash +cd /language/documentation/tutorial +``` + + +
+Visual Studio Code Move support +There is official Move support for Visual Studio Code. You need to install +the move analyzer first: + +```bash +cargo install --path language/move-analyzer +``` + +Now you can install the VS extension by opening VS Code, searching for the "move-analyzer" in +the Extension Pane, and installing it. More detailed instructions can be found +in the extension's [README](https://github.com/move-language/move/tree/main/language/move-analyzer/editors/code). +
+ + +## Step 1: Writing my first Move module + +Change directory into the [`step_1/BasicCoin`](./step_1/BasicCoin) directory. +You should see a directory called `sources` -- this is the place where all +the Move code for this package lives. You should also see a +`Move.toml` file as well. This file specifies dependencies and other information about +the package; if you're familiar with Rust and Cargo, the `Move.toml` file +is similar to the `Cargo.toml` file, and the `sources` directory similar to +the `src` directory. + +Let's take a look at some Move code! Open up +[`sources/FirstModule.move`](./step_1/BasicCoin/sources/FirstModule.move) in +your editor of choice. The first thing you'll see is this: + +``` +// sources/FirstModule.move +module 0xCAFE::BasicCoin { + ... +} +``` + +This is defining a Move +[module](https://move-language.github.io/move/modules-and-scripts.html). Modules are the +building blocks of Move code, and are defined with a specific address -- the +address that the module can be published under. In this case, the `BasicCoin` +module can only be published under `0xCAFE`. + +Let's now take a look at the next part of this file where we define a +[struct](https://move-language.github.io/move/structs-and-resources.html) +to represent a `Coin` with a given `value`: + +``` +module 0xCAFE::BasicCoin { + struct Coin has key { + value: u64, + } + ... +} +``` + +Looking at the rest of the file, we see a function definition that creates a `Coin` struct and stores it under an account: + +``` +module 0xCAFE::BasicCoin { + struct Coin has key { + value: u64, + } + + public fun mint(account: signer, value: u64) { + move_to(&account, Coin { value }) + } +} +``` + +Let's take a look at this function and what it's saying: +* It takes a [`signer`](https://move-language.github.io/move/signer.html) -- an + unforgeable token that represents control over a particular address, and + a `value` to mint. +* It creates a `Coin` with the given value and stores it under the + `account` using the `move_to` operator. + +Let's make sure it builds! This can be done with the `build` command from within the package folder ([`step_1/BasicCoin`](./step_1/BasicCoin/)): + +```bash +move build +``` + +
+Advanced concepts and references + +* You can create an empty Move package by calling: + ```bash + move new + ``` +* Move code can also live a number of other places. More information on the + Move package system can be found in the [Move + book](https://move-language.github.io/move/packages.html) +* More information on the `Move.toml` file can be found in the [package section of the Move book](https://move-language.github.io/move/packages.html#movetoml). +* Move also supports the idea of [named + addresses](https://move-language.github.io/move/address.html#named-addresses), Named + addresses are a way to parametrize Move source code so that you can compile + the module using different values for `NamedAddr` to get different bytecode + that you can deploy, depending on what address(es) you control. They are used quite frequently, and can be defined in the `Move.toml` file in the `[addresses]` section, e.g., + ``` + [addresses] + SomeNamedAddress = "0xC0FFEE" + ``` +* [Structures](https://move-language.github.io/move/structs-and-resources.html) in Move + can be given different + [abilities](https://move-language.github.io/move/abilities.html) that describe what + can be done with that type. There are four different abilities: + - `copy`: Allows values of types with this ability to be copied. + - `drop`: Allows values of types with this ability to be popped/dropped. + - `store`: Allows values of types with this ability to exist inside a struct in global storage. + - `key`: Allows the type to serve as a key for global storage operations. + + So in the `BasicCoin` module we are saying that the `Coin` struct can be used as a key + in global storage and, because it has no other abilities, it cannot be + copied, dropped, or stored as a non-key value in storage. So you can't copy + coins, and you also can't lose coins by accident! +* [Functions](https://move-language.github.io/move/functions.html) are default + private, and can also be `public`, + [`public(friend)`](https://move-language.github.io/move/friends.html), or + `public(script)`. The last of these states that this function can be + called from a transaction script. `public(script)` functions can also be + called by other `public(script)` functions. +* `move_to` is one of the [five different global storage + operators](https://move-language.github.io/move/global-storage-operators.html). +
+ +## Step 2: Adding unit tests to my first Move module + +Now that we've taken a look at our first Move module, we'll take a look at a +test to make sure minting works the way we expect it to by changing directory +to [`step_2/BasicCoin`](./step_2/BasicCoin). Unit tests in Move are similar to +unit tests in Rust if you're familiar with them -- tests are annotated with +`#[test]` and written like normal Move functions. + +You can run the tests with the `move test` command: + +```bash +move test +``` + +Let's now take a look at the contents of the [`FirstModule.move` +file](./step_2/BasicCoin/sources/FirstModule.move). The first new thing you'll +see is this test: + +``` +module 0xCAFE::BasicCoin { + ... + // Declare a unit test. It takes a signer called `account` with an + // address value of `0xC0FFEE`. + #[test(account = @0xC0FFEE)] + fun test_mint_10(account: signer) acquires Coin { + let addr = 0x1::signer::address_of(&account); + mint(account, 10); + // Make sure there is a `Coin` resource under `addr` with a value of `10`. + // We can access this resource and its value since we are in the + // same module that defined the `Coin` resource. + assert!(borrow_global(addr).value == 10, 0); + } +} +``` + +This is declaring a unit test called `test_mint_10` that mints a `Coin` struct +under the `account` with a `value` of `10`. It is then checking that the minted +coin in storage has the value that is expected with the `assert!` call. If the +assertion fails the unit test will fail. + +
+Advanced concepts and exercises + +* There are a number of test-related annotations that are worth exploring, they + can be found + [here](https://github.com/move-language/move/blob/main/language/changes/4-unit-testing.md#testing-annotations-their-meaning-and-usage). + You'll see some of these used in Step 5. +* Before running unit tests, you'll always need to add a dependency on the Move + standard library. This can be done by adding an entry to the `[dependencies]` + section of the `Move.toml`, e.g., + + ```toml + [dependencies] + MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } + ``` + + Note that you may need to alter the path to point to the `move-stdlib` directory under + `/language`. You can also specify git dependencies. You can read more on Move + package dependencies [here](https://move-language.github.io/move/packages.html#movetoml). + + +#### Exercises +* Change the assertion to `11` so that the test fails. Find a flag that you can + pass to the `move test` command that will show you the global state when + the test fails. It should look something like this: + ``` + ┌── test_mint_10 ────── + │ error[E11001]: test failure + │ ┌─ ./sources/FirstModule.move:24:9 + │ │ + │ 18 │ fun test_mint_10(account: signer) acquires Coin { + │ │ ------------ In this function in 0xcafe::BasicCoin + │ · + │ 24 │ assert!(borrow_global(addr).value == 11, 0); + │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to abort but it aborted with 0 here + │ + │ + │ ────── Storage state at point of failure ────── + │ 0xc0ffee: + │ => key 0xcafe::BasicCoin::Coin { + │ value: 10 + │ } + └────────────────── + ``` +* Find a flag that allows you to gather test coverage information, and + then play around with using the `move coverage` command to look at + coverage statistics and source coverage. + +
+ +## Step 3: Designing my `BasicCoin` module + +In this section, we are going to design a module implementing a basic coin and balance interface, where coins can +be minted and transferred between balances held under different addresses. + +The signatures of the public Move function are the following: + +``` +/// Publish an empty balance resource under `account`'s address. This function must be called before +/// minting or transferring to the account. +public fun publish_balance(account: &signer) { ... } + +/// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner. +public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance { ... } + +/// Returns the balance of `owner`. +public fun balance_of(owner: address): u64 acquires Balance { ... } + +/// Transfers `amount` of tokens from `from` to `to`. +public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { ... } +``` + +Next we look at the data structs we need for this module. + +A Move module doesn't have its own storage. Instead, Move "global storage" (what we call our +blockchain state) is indexed by addresses. Under each address there are Move modules (code) and Move resources (values). + +The global storage looks roughly like this in Rust syntax: + +```rust +struct GlobalStorage { + resources: Map> + modules: Map> +} +``` + +The Move resource storage under each address is a map from types to values. (An observant reader might observe that +this means each address can only have one value of each type.) This conveniently provides us a native mapping indexed +by addresses. In our `BasicCoin` module, we define the following `Balance` resource representing the number of coins +each address holds: + +``` +/// Struct representing the balance of each address. +struct Balance has key { + coin: Coin // same Coin from Step 1 +} +``` + +Roughly the Move blockchain state should look like this: + +![](diagrams/move_state.png) + +#### Advanced topics: +
+public(script) functions + +Only functions with `public(script)` visibility can be invoked directly in transactions. So if you would like to call the `transfer` +method directly from a transaction, you'll want to change its signature to: +``` +public(script) fun transfer(from: signer, to: address, amount: u64) acquires Balance { ... } +``` +Read more on Move function visibilities [here](https://move-language.github.io/move/functions.html#visibility). +
+
+Comparison with Ethereum/Solidity + +In most Ethereum [ERC-20]((https://ethereum.org/en/developers/docs/standards/tokens/erc-20/)) contracts, the balance of each address is stored in a _state variable_ of type +mapping(address => uint256). This state variable is stored in the storage of a particular smart contract. + +The Ethereum blockchain state might look like this: + +![](diagrams/solidity_state.png) +
+ +## Step 4: Implementing my `BasicCoin` module + +We have created a Move package for you in folder `step_4` called `BasicCoin`. The `sources` folder contains source code for +all your Move modules in the package, including `BasicCoin.move`. In this section, we will take a closer look at the +implementation of the methods inside [`BasicCoin.move`](./step_4/sources/BasicCoin.move). + +### Compiling our code + +Let's first try building the code using Move package by running the following command +in [`step_4/BasicCoin`](./step_4/BasicCoin) folder: +```bash +move build +``` + +### Implementation of methods +Now let's take a closer look at the implementation of the methods inside [`BasicCoin.move`](./step_4/BasicCoin/sources/BasicCoin.move). + +
+Method publish_balance + +This method publishes a `Balance` resource to a given address. Since this resource is needed to receive coins through +minting or transferring, `publish_balance` method must be called by a user before they can receive money, including the +module owner. + +This method uses a `move_to` operation to publish the resource: + +``` +let empty_coin = Coin { value: 0 }; +move_to(account, Balance { coin: empty_coin }); +``` +
+
+Method mint + +`mint` method mints coins to a given account. Here we require that `mint` must be approved +by the module owner. We enforce this using the assert statement: +``` +assert!(signer::address_of(&module_owner) == MODULE_OWNER, ENOT_MODULE_OWNER); +``` +Assert statements in Move can be used in this way: `assert!(, );`. This means that if the `` +is false, then abort the transaction with ``. Here `MODULE_OWNER` and `ENOT_MODULE_OWNER` are both constants +defined at the beginning of the module. The standard library's [`error` module] also defines common error categories we can use. +It is important to note that Move is transactional in its execution -- so +if an [abort](https://move-language.github.io/move/abort-and-assert.html) is raised no unwinding of state +needs to be performed, as no changes from that transaction will be persisted to the blockchain. + +[`error` module]: https://github.com/move-language/move/blob/main/language/move-stdlib/docs/error.md + +We then deposit a coin with value `amount` to the balance of `mint_addr`. +``` +deposit(mint_addr, Coin { value: amount }); +``` +
+ +
+Method balance_of + +We use `borrow_global`, one of the global storage operators, to read from the global storage. +``` +borrow_global(owner).coin.value + | | \ / + resource type address field names +``` +
+ +
+Method transfer + +This function withdraws tokens from `from`'s balance and deposits the tokens into `to`s balance. We take a closer look +at `withdraw` helper function: +``` +fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } +} +``` +At the beginning of the method, we assert that the withdrawing account has enough balance. We then use `borrow_global_mut` +to get a mutable reference to the global storage, and `&mut` is used to create a [mutable reference](https://move-language.github.io/move/references.html) to a field of a +struct. We then modify the balance through this mutable reference and return a new coin with the withdrawn amount. +
+ +### Exercises +There are two `TODO`s in our module, left as exercises for the reader: +- Finish implementing the `publish_balance` method. +- Implement the `deposit` method. + +The solution to this exercise can be found in [`step_4_sol`](./step_4_sol) folder. + +**Bonus exercise** +- What would happen if we deposit too many tokens to a balance? + +## Step 5: Adding and using unit tests with the `BasicCoin` module + +In this step we're going to take a look at all the different unit tests +we've written to cover the code we wrote in step 4. We're also going to +take a look at some tools we can use to help us write tests. + +To get started, run the `package test` command in the [`step_5/BasicCoin`](./step_5/BasicCoin) folder + +```bash +move test +``` + +You should see something like this: + +``` +INCLUDING DEPENDENCY MoveStdlib +BUILDING BasicCoin +Running Move unit tests +[ PASS ] 0xcafe::BasicCoin::can_withdraw_amount +[ PASS ] 0xcafe::BasicCoin::init_check_balance +[ PASS ] 0xcafe::BasicCoin::init_non_owner +[ PASS ] 0xcafe::BasicCoin::publish_balance_already_exists +[ PASS ] 0xcafe::BasicCoin::publish_balance_has_zero +[ PASS ] 0xcafe::BasicCoin::withdraw_dne +[ PASS ] 0xcafe::BasicCoin::withdraw_too_much +Test result: OK. Total tests: 7; passed: 7; failed: 0 +``` + +Taking a look at the tests in the +[`BasicCoin` module](./step_5/BasicCoin/sources/BasicCoin.move) we've tried +to keep each unit test to testing one particular behavior. + +
+Exercise + +After taking a look at the tests, try and write a unit test called +`balance_of_dne` in the `BasicCoin` module that tests the case where a +`Balance` resource doesn't exist under the address that `balance_of` is being +called on. It should only be a couple lines! + +The solution to this exercise can be found in [`step_5_sol`](./step_5_sol) + +
+ +## Step 6: Making my `BasicCoin` module generic + +In Move, we can use generics to define functions and structs over different input data types. Generics are a great +building block for library code. In this section, we are going to make our simple `BasicCoin` module generic so that it can +serve as a library module that can be used by other user modules. + +First, we add type parameters to our data structs: +``` +struct Coin has store { + value: u64 +} + +struct Balance has key { + coin: Coin +} +``` + +We also add type parameters to our methods in the same manner. For example, `withdraw` becomes the following: +``` +fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } +} +``` +Take a look at [`step_6/BasicCoin/sources/BasicCoin.move`](./step_6/BasicCoin/sources/BasicCoin.move) to see the full implementation. + +At this point, readers who are familiar with Ethereum might notice that this module serves a similar purpose as +the [ERC20 token standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/), which provides an +interface for implementing fungible tokens in smart contracts. One key advantage of using generics is the ability +to reuse code since the generic library module already provides a standard implementation and the instantiating module +can provide customizations by wrapping the standard implementation. + +We provide a little module called [`MyOddCoin`](./step_6/BasicCoin/sources/MyOddCoin.move) that instantiates +the `Coin` type and customizes its transfer policy: only odd number of coins can be transferred. We also include two +[tests](./step_6/BasicCoin/sources/MyOddCoin.move) to test this behavior. You can use the commands you learned in step 2 and step 5 to run the tests. + +#### Advanced topics: +
+ +## Advanced steps + +Before moving on to the next steps, let's make sure you have all the prover dependencies installed. + +Try running `boogie /version `. If an error message shows up saying "command not found: boogie", you will have to run the +setup script and source your profile: +```bash +# run the following in move repo root directory +./scripts/dev_setup.sh -yp +source ~/.profile +``` +## Step 7: Use the Move prover + +Smart contracts deployed on the blockchain may manipulate high-value assets. As a technique that uses strict +mathematical methods to describe behavior and reason correctness of computer systems, formal verification +has been used in blockchains to prevent bugs in smart contracts. [ +The Move prover](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/prover-guide.md) +is an evolving formal verification tool for smart contracts written in the Move language. The user can specify +functional properties of smart contracts +using the [Move Specification Language (MSL)](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/spec-lang.md) +and then use the prover to automatically check them statically. +To illustrate how the prover is used, we have added the following code snippet to +the [BasicCoin.move](./step_7/BasicCoin/sources/BasicCoin.move): + +``` + spec balance_of { + pragma aborts_if_is_strict; + } +``` + +Informally speaking, the block `spec balance_of {...}` contains the property specification of the method `balance_of`. + +Let's first run the prover using the following command inside [`BasicCoin` directory](./step_7/BasicCoin/): +```bash +move prove +``` + +which outputs the following error information: + +``` +error: abort not covered by any of the `aborts_if` clauses + ┌─ ./sources/BasicCoin.move:38:5 + │ +35 │ borrow_global>(owner).coin.value + │ ------------- abort happened here with execution failure + · +38 │ ╭ spec balance_of { +39 │ │ pragma aborts_if_is_strict; +40 │ │ } + │ ╰─────^ + │ + = at ./sources/BasicCoin.move:34: balance_of + = owner = 0x29 + = at ./sources/BasicCoin.move:35: balance_of + = ABORTED + +Error: exiting with verification errors +``` + +The prover basically tells us that we need to explicitly specify the condition under which the function `balance_of` will abort, which is caused by calling the function `borrow_global` when `owner` does not own the resource `Balance`. To remove this error information, we add an `aborts_if` condition as follows: + +``` + spec balance_of { + pragma aborts_if_is_strict; + aborts_if !exists>(owner); + } +``` +After adding this condition, try running the `prove` command again to confirm that there are no verification errors: +```bash +move prove +``` +Apart from the abort condition, we also want to define the functional properties. In Step 8, we will give more detailed introduction to the prover by specifying properties for the methods defined the `BasicCoin` module. + + +## Step 8: Write formal specifications for the `BasicCoin` module + +
+ + Method withdraw + +The signature of the method `withdraw` is given below: +``` +fun withdraw(addr: address, amount: u64) : Coin acquires Balance +``` + +The method withdraws tokens with value `amount` from the address `addr` and returns a created Coin of value `amount`. The method `withdraw` aborts when 1) `addr` does not have the resource `Balance` or 2) the number of tokens in `addr` is smaller than `amount`. We can define conditions like this: + +``` + spec withdraw { + let balance = global>(addr).coin.value; + aborts_if !exists>(addr); + aborts_if balance < amount; + } +``` + +As we can see here, a spec block can contain let bindings which introduce names for expressions. `global(address): T` is a built-in function that returns the resource value at `addr`. `balance` is the number of tokens owned by `addr`. `exists(address): bool` is a built-in function that returns true if the resource T exists at address. Two `aborts_if` clauses correspond to the two conditions mentioned above. In general, if a function has more than one `aborts_if` condition, those conditions are or-ed with each other. By default, if a user wants to specify aborts conditions, all possible conditions need to be listed. Otherwise, the prover will generate a verification error. However, if `pragma aborts_if_is_partial` is defined in the spec block, the combined aborts condition (the or-ed individual conditions) only *imply* that the function aborts. The reader can refer to the +[MSL](https://github.com/move-language/move/blob/main/language/move-prover/doc/user/spec-lang.md) document for more information. + +The next step is to define functional properties, which are described in the two `ensures` clauses below. First, by using the `let post` binding, `balance_post` represents the balance of `addr` after the execution, which should be equal to `balance - amount`. Then, the return value (denoted as `result`) should be a coin with value `amount`. + +``` + spec withdraw { + let balance = global>(addr).coin.value; + aborts_if !exists>(addr); + aborts_if balance < amount; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance - amount; + ensures result == Coin { value: amount }; + } +``` +
+ +
+ Method deposit + + + +The signature of the method `deposit` is given below: + +``` +fun deposit(addr: address, check: Coin) acquires Balance +``` + +The method deposits the `check` into `addr`. The specification is defined below: + +``` + spec deposit { + let balance = global>(addr).coin.value; + let check_value = check.value; + + aborts_if !exists>(addr); + aborts_if balance + check_value > MAX_U64; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance + check_value; + } +``` + +`balance` represents the number of tokens in `addr` before execution and `check_value` represents the number of tokens to be deposited. The method would abort if 1) `addr` does not have the resource `Balance` or 2) the sum of `balance` and `check_value` is greater than the maxium value of the type `u64`. The functional property checks that the balance is correctly updated after the execution. + +
+ +
+ + Method transfer + + +The signature of the method `transfer` is given below: + +``` +public fun transfer(from: &signer, to: address, amount: u64, _witness: CoinType) acquires Balance +``` + +The method transfers the `amount` of coin from the account of `from` to the address `to`. The specification is given below: + +``` + spec transfer { + let addr_from = signer::address_of(from); + + let balance_from = global>(addr_from).coin.value; + let balance_to = global>(to).coin.value; + let post balance_from_post = global>(addr_from).coin.value; + let post balance_to_post = global>(to).coin.value; + + ensures balance_from_post == balance_from - amount; + ensures balance_to_post == balance_to + amount; + } +``` + +`addr_from` is the address of `from`. Then the balances of `addr_from` and `to` before and after the execution are obtained. +The `ensures` clauses specify that the `amount` number of tokens is deducted from `addr_from` and added to `to`. However, the prover will generate the error information as below: + +``` +error: post-condition does not hold + ┌─ ./sources/BasicCoin.move:57:9 + │ +62 │ ensures balance_from_post == balance_from - amount; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ + ... +``` + +The property is not held when `addr_from` is equal to `to`. As a result, we could add an assertion `assert!(from_addr != to)` in the method to make sure that `addr_from` is not equal to `to`. + +
+ + +
+ + Exercises + +- Implement the `aborts_if` conditions for the `transfer` method. +- Implement the specification for the `mint` and `publish_balance` method. + +The solution to this exercise can be found in [`step_8_sol`](./step_8_sol). diff --git a/vendors/move/crates/documentation/tutorial/diagrams/move_state.png b/vendors/move/crates/documentation/tutorial/diagrams/move_state.png new file mode 100644 index 000000000..bf8831b3f Binary files /dev/null and b/vendors/move/crates/documentation/tutorial/diagrams/move_state.png differ diff --git a/vendors/move/crates/documentation/tutorial/diagrams/solidity_state.png b/vendors/move/crates/documentation/tutorial/diagrams/solidity_state.png new file mode 100644 index 000000000..af5dd076d Binary files /dev/null and b/vendors/move/crates/documentation/tutorial/diagrams/solidity_state.png differ diff --git a/vendors/move/crates/documentation/tutorial/step_1/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_1/BasicCoin/Move.toml new file mode 100644 index 000000000..d5fc1dc06 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_1/BasicCoin/Move.toml @@ -0,0 +1,3 @@ +[package] +name = "BasicCoin" +version = "0.0.0" diff --git a/vendors/move/crates/documentation/tutorial/step_1/BasicCoin/sources/FirstModule.move b/vendors/move/crates/documentation/tutorial/step_1/BasicCoin/sources/FirstModule.move new file mode 100644 index 000000000..117401844 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_1/BasicCoin/sources/FirstModule.move @@ -0,0 +1,9 @@ +module 0xCAFE::BasicCoin { + struct Coin has key { + value: u64, + } + + public fun mint(account: signer, value: u64) { + move_to(&account, Coin { value }) + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_2/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_2/BasicCoin/Move.toml new file mode 100644 index 000000000..c4f70936a --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_2/BasicCoin/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_2/BasicCoin/sources/FirstModule.move b/vendors/move/crates/documentation/tutorial/step_2/BasicCoin/sources/FirstModule.move new file mode 100644 index 000000000..d2996f1a1 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_2/BasicCoin/sources/FirstModule.move @@ -0,0 +1,26 @@ +module 0xCAFE::BasicCoin { + // Only included in compilation for testing. Similar to #[cfg(testing)] + // in Rust. Imports the `Signer` module from the MoveStdlib package. + #[test_only] + use std::signer; + + struct Coin has key { + value: u64, + } + + public fun mint(account: signer, value: u64) { + move_to(&account, Coin { value }) + } + + // Declare a unit test. It takes a signer called `account` with an + // address value of `0xC0FFEE`. + #[test(account = @0xC0FFEE)] + fun test_mint_10(account: signer) acquires Coin { + let addr = signer::address_of(&account); + mint(account, 10); + // Make sure there is a `Coin` resource under `addr` with a value of `10`. + // We can access this resource and its value since we are in the + // same module that defined the `Coin` resource. + assert!(borrow_global(addr).value == 10, 0); + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_2_sol/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_2_sol/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_2_sol/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_2_sol/BasicCoin/sources/FirstModule.move b/vendors/move/crates/documentation/tutorial/step_2_sol/BasicCoin/sources/FirstModule.move new file mode 100644 index 000000000..2401167db --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_2_sol/BasicCoin/sources/FirstModule.move @@ -0,0 +1,26 @@ +module 0xCAFE::BasicCoin { + // Only included in compilation for testing. Similar to #[cfg(testing)] + // in Rust. + #[test_only] + use std::signer; + + struct Coin has key { + value: u64, + } + + public fun mint(account: signer, value: u64) { + move_to(&account, Coin { value }) + } + + // Declare a unit test. It takes a signer called `account` with an + // address value of `0xC0FFEE`. + #[test(account = @0xC0FFEE)] + fun test_mint_10(account: signer) acquires Coin { + let addr = signer::address_of(&account); + mint(account, 10); + // Make sure there is a `Coin` resource under `addr` with a value of `10`. + // We can access this resource and its value since we are in the + // same module that defined the `Coin` resource. + assert!(borrow_global(addr).value == 10, 0); + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_2_sol/solution_commands b/vendors/move/crates/documentation/tutorial/step_2_sol/solution_commands new file mode 100644 index 000000000..54ab34115 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_2_sol/solution_commands @@ -0,0 +1,11 @@ +# Exercise 1 +move test -g + +# Exercise 2 +move test --coverage + +Followed by: + +move coverage summary +move coverage summary --summarize-functions +move coverage source --module BasicCoin diff --git a/vendors/move/crates/documentation/tutorial/step_3/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_3/BasicCoin.move new file mode 100644 index 000000000..67d70a60e --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_3/BasicCoin.move @@ -0,0 +1,22 @@ +module NamedAddr::BasicCoin { + struct Coin has store { + value: u64 + } + + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { .. } + + /// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner. + public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance { .. } + + /// Returns the balance of `owner`. + public fun balance_of(owner: address): u64 acquires Balance { .. } + + /// Transfers `amount` of tokens from `from` to `to`. + public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { .. } +} diff --git a/vendors/move/crates/documentation/tutorial/step_4/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_4/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_4/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_4/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_4/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..ad469bcf1 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_4/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,69 @@ +/// This module defines a minimal Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Address of the owner of this module + const MODULE_OWNER: address = @NamedAddr; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + + struct Coin has store { + value: u64 + } + + /// Struct representing the balance of each address. + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { + // TODO: add an assert to check that `account` doesn't already have a `Balance` resource. + let empty_coin = Coin { value: 0 }; + move_to(account, Balance { coin: empty_coin }); + } + + /// Initialize this module. + public fun mint(module_owner: &signer, mint_addr: address, amount: u64) { + // Only the owner of the module can initialize this module + assert!(signer::address_of(module_owner) == MODULE_OWNER, ENOT_MODULE_OWNER); + + // Deposit `amount` of tokens to `mint_addr`'s balance + deposit(mint_addr, Coin { value: amount }); + } + + /// Returns the balance of `owner`. + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global(owner).coin.value + } + + /// Transfers `amount` of tokens from `from` to `to`. + public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { + let check = withdraw(signer::address_of(from), amount); + deposit(to, check); + } + + /// Withdraw `amount` number of tokens from the balance under `addr`. + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + // balance must be greater than the withdraw amount + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + /// Deposit `amount` number of tokens to the balance under `addr`. + fun deposit(_addr: address, check: Coin) { + // TODO: follow the implementation of `withdraw` and implement me! + let Coin { value: _amount } = check; // unpacks the check + + // Get a mutable reference of addr's balance's coin value + + // Increment the value by `amount` + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_4_sol/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_4_sol/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_4_sol/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_4_sol/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_4_sol/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..3b41ce593 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_4_sol/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,67 @@ +/// This module defines a minimal Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Address of the owner of this module + const MODULE_OWNER: address = @NamedAddr; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + + struct Coin has store { + value: u64 + } + + /// Struct representing the balance of each address. + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists(signer::address_of(account)), EALREADY_HAS_BALANCE); + move_to(account, Balance { coin: empty_coin }); + } + + /// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner. + public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance { + // Only the owner of the module can initialize this module + assert!(signer::address_of(module_owner) == MODULE_OWNER, ENOT_MODULE_OWNER); + + // Deposit `amount` of tokens to `mint_addr`'s balance + deposit(mint_addr, Coin { value: amount }); + } + + /// Returns the balance of `owner`. + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global(owner).coin.value + } + + /// Transfers `amount` of tokens from `from` to `to`. + public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { + let check = withdraw(signer::address_of(from), amount); + deposit(to, check); + } + + /// Withdraw `amount` number of tokens from the balance under `addr`. + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + // balance must be greater than the withdraw amount + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + /// Deposit `amount` number of tokens to the balance under `addr`. + fun deposit(addr: address, check: Coin) acquires Balance { + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_5/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_5/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_5/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_5/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_5/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..f90155717 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_5/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,126 @@ +/// This module defines a minimal Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Address of the owner of this module + const MODULE_OWNER: address = @NamedAddr; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + + struct Coin has store { + value: u64 + } + + /// Struct representing the balance of each address. + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists(signer::address_of(account)), EALREADY_HAS_BALANCE); + move_to(account, Balance { coin: empty_coin }); + } + + /// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner. + public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance { + // Only the owner of the module can initialize this module + assert!(signer::address_of(module_owner) == MODULE_OWNER, ENOT_MODULE_OWNER); + + // Deposit `amount` of tokens to `mint_addr`'s balance + deposit(mint_addr, Coin { value: amount }); + } + + /// Returns the balance of `owner`. + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global(owner).coin.value + } + + /// Transfers `amount` of tokens from `from` to `to`. + public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { + let check = withdraw(signer::address_of(from), amount); + deposit(to, check); + } + + /// Withdraw `amount` number of tokens from the balance under `addr`. + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + // balance must be greater than the withdraw amount + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + /// Deposit `amount` number of tokens to the balance under `addr`. + fun deposit(addr: address, check: Coin) acquires Balance{ + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } + + #[test(account = @0x1)] // Creates a signer for the `account` argument with address `@0x1` + #[expected_failure] // This test should abort + fun mint_non_owner(account: signer) acquires Balance { + // Make sure the address we've chosen doesn't match the module + // owner address + publish_balance(&account); + assert!(signer::address_of(&account) != MODULE_OWNER, 0); + mint(&account, @0x1, 10); + } + + #[test(account = @NamedAddr)] // Creates a signer for the `account` argument with the value of the named address `NamedAddr` + fun mint_check_balance(account: signer) acquires Balance { + let addr = signer::address_of(&account); + publish_balance(&account); + mint(&account, @NamedAddr, 42); + assert!(balance_of(addr) == 42, 0); + } + + #[test(account = @0x1)] + fun publish_balance_has_zero(account: signer) acquires Balance { + let addr = signer::address_of(&account); + publish_balance(&account); + assert!(balance_of(addr) == 0, 0); + } + + #[test(account = @0x1)] + #[expected_failure(abort_code = 2)] // Can specify an abort code + fun publish_balance_already_exists(account: signer) { + publish_balance(&account); + publish_balance(&account); + } + + // EXERCISE: Write `balance_of_dne` test here! + + #[test] + #[expected_failure] + fun withdraw_dne() acquires Balance { + // Need to unpack the coin since `Coin` is a resource + Coin { value: _ } = withdraw(@0x1, 0); + } + + #[test(account = @0x1)] + #[expected_failure] // This test should fail + fun withdraw_too_much(account: signer) acquires Balance { + let addr = signer::address_of(&account); + publish_balance(&account); + Coin { value: _ } = withdraw(addr, 1); + } + + #[test(account = @NamedAddr)] + fun can_withdraw_amount(account: signer) acquires Balance { + publish_balance(&account); + let amount = 1000; + let addr = signer::address_of(&account); + mint(&account, addr, amount); + let Coin { value } = withdraw(addr, amount); + assert!(value == amount, 0); + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_5_sol/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_5_sol/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_5_sol/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_5_sol/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_5_sol/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..a6e31ba55 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_5_sol/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,130 @@ +/// This module defines a minimal Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Address of the owner of this module + const MODULE_OWNER: address = @NamedAddr; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + + struct Coin has store { + value: u64 + } + + /// Struct representing the balance of each address. + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists(signer::address_of(account)), EALREADY_HAS_BALANCE); + move_to(account, Balance { coin: empty_coin }); + } + + /// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner. + public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance { + // Only the owner of the module can initialize this module + assert!(signer::address_of(module_owner) == MODULE_OWNER, ENOT_MODULE_OWNER); + + // Deposit `amount` of tokens to `mint_addr`'s balance + deposit(mint_addr, Coin { value: amount }); + } + + /// Returns the balance of `owner`. + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global(owner).coin.value + } + + /// Transfers `amount` of tokens from `from` to `to`. + public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { + let check = withdraw(signer::address_of(from), amount); + deposit(to, check); + } + + /// Withdraw `amount` number of tokens from the balance under `addr`. + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + // balance must be greater than the withdraw amount + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + /// Deposit `amount` number of tokens to the balance under `addr`. + fun deposit(addr: address, check: Coin) acquires Balance{ + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } + + #[test(account = @0x1)] + #[expected_failure] // This test should abort + fun mint_non_owner(account: signer) acquires Balance { + // Make sure the address we've chosen doesn't match the module + // owner address + publish_balance(&account); + assert!(signer::address_of(&account) != MODULE_OWNER, 0); + mint(&account, @0x1, 10); + } + + #[test(account = @NamedAddr)] + fun mint_check_balance(account: signer) acquires Balance { + let addr = signer::address_of(&account); + publish_balance(&account); + mint(&account, @NamedAddr, 42); + assert!(balance_of(addr) == 42, 0); + } + + #[test(account = @0x1)] + fun publish_balance_has_zero(account: signer) acquires Balance { + let addr = signer::address_of(&account); + publish_balance(&account); + assert!(balance_of(addr) == 0, 0); + } + + #[test(account = @0x1)] + #[expected_failure(abort_code = 2)] // Can specify an abort code + fun publish_balance_already_exists(account: signer) { + publish_balance(&account); + publish_balance(&account); + } + + #[test] + #[expected_failure] + fun balance_of_dne() acquires Balance { + balance_of(@0x1); + } + + #[test] + #[expected_failure] + fun withdraw_dne() acquires Balance { + // Need to unpack the coin since `Coin` is a resource + Coin { value: _ } = withdraw(@0x1, 0); + } + + #[test(account = @0x1)] + #[expected_failure] // This test should fail + fun withdraw_too_much(account: signer) acquires Balance { + let addr = signer::address_of(&account); + publish_balance(&account); + Coin { value: _ } = withdraw(addr, 1); + } + + #[test(account = @NamedAddr)] + fun can_withdraw_amount(account: signer) acquires Balance { + publish_balance(&account); + let amount = 1000; + let addr = signer::address_of(&account); + mint(&account, addr, amount); + let Coin { value } = withdraw(addr, amount); + assert!(value == amount, 0); + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..d7354c6ec --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,58 @@ +/// This module defines a minimal and generic Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + + struct Coin has store { + value: u64 + } + + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists>(signer::address_of(account)), EALREADY_HAS_BALANCE); + move_to(account, Balance { coin: empty_coin }); + } + + /// Mint `amount` tokens to `mint_addr`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the minting policy. + public fun mint(mint_addr: address, amount: u64, _witness: CoinType) acquires Balance { + // Deposit `total_value` amount of tokens to mint_addr's balance + deposit(mint_addr, Coin { value: amount }); + } + + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global>(owner).coin.value + } + + /// Transfers `amount` of tokens from `from` to `to`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the transferring policy. + public fun transfer(from: &signer, to: address, amount: u64, _witness: CoinType) acquires Balance { + let check = withdraw(signer::address_of(from), amount); + deposit(to, check); + } + + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + fun deposit(addr: address, check: Coin) acquires Balance{ + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/sources/MyOddCoin.move b/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/sources/MyOddCoin.move new file mode 100644 index 000000000..1ca302bda --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_6/BasicCoin/sources/MyOddCoin.move @@ -0,0 +1,46 @@ +/// Module implementing an odd coin, where only odd number of coins can be +/// transferred each time. +module NamedAddr::MyOddCoin { + use std::signer; + use NamedAddr::BasicCoin; + + struct MyOddCoin has drop {} + + const ENOT_ODD: u64 = 0; + + public fun setup_and_mint(account: &signer, amount: u64) { + BasicCoin::publish_balance(account); + BasicCoin::mint(signer::address_of(account), amount, MyOddCoin {}); + } + + public fun transfer(from: &signer, to: address, amount: u64) { + // amount must be odd. + assert!(amount % 2 == 1, ENOT_ODD); + BasicCoin::transfer(from, to, amount, MyOddCoin {}); + } + + /* + Unit tests + */ + #[test(from = @0x42, to = @0x10)] + fun test_odd_success(from: signer, to: signer) { + setup_and_mint(&from, 42); + setup_and_mint(&to, 10); + + // transfer an odd number of coins so this should succeed. + transfer(&from, @0x10, 7); + + assert!(BasicCoin::balance_of(@0x42) == 35, 0); + assert!(BasicCoin::balance_of(@0x10) == 17, 0); + } + + #[test(from = @0x42, to = @0x10)] + #[expected_failure] + fun test_not_odd_failure(from: signer, to: signer) { + setup_and_mint(&from, 42); + setup_and_mint(&to, 10); + + // transfer an even number of coins so this should fail. + transfer(&from, @0x10, 8); + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_7/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_7/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_7/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_7/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_7/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..3a5ec81e3 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_7/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,62 @@ +/// This module defines a minimal and generic Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + + struct Coin has store { + value: u64 + } + + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists>(signer::address_of(account)), EALREADY_HAS_BALANCE); + move_to(account, Balance { coin: empty_coin }); + } + + /// Mint `amount` tokens to `mint_addr`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the minting policy. + public fun mint(mint_addr: address, amount: u64, _witness: CoinType) acquires Balance { + // Deposit `total_value` amount of tokens to mint_addr's balance + deposit(mint_addr, Coin { value: amount }); + } + + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global>(owner).coin.value + } + + spec balance_of { + pragma aborts_if_is_strict; + } + + /// Transfers `amount` of tokens from `from` to `to`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the transferring policy. + public fun transfer(from: &signer, to: address, amount: u64, _witness: CoinType) acquires Balance { + let check = withdraw(signer::address_of(from), amount); + deposit(to, check); + } + + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + fun deposit(addr: address, check: Coin) acquires Balance{ + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_8/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_8/BasicCoin/Move.toml new file mode 100644 index 000000000..6052ad692 --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_8/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xCAFE" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_8/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_8/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..d936ca43f --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_8/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,100 @@ +/// This module defines a minimal and generic Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + const EEQUAL_ADDR: u64 = 4; + + struct Coin has store { + value: u64 + } + + struct Balance has key { + coin: Coin + } + + /// Publish an empty balance resource under `account`'s address. This function must be called before + /// minting or transferring to the account. + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists>(signer::address_of(account)), EALREADY_HAS_BALANCE); + move_to(account, Balance { coin: empty_coin }); + } + + /// Mint `amount` tokens to `mint_addr`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the minting policy. + public fun mint(mint_addr: address, amount: u64, _witness: CoinType) acquires Balance { + // Deposit `total_value` amount of tokens to mint_addr's balance + deposit(mint_addr, Coin { value: amount }); + } + + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global>(owner).coin.value + } + + spec balance_of { + pragma aborts_if_is_strict; + aborts_if !exists>(owner); + } + + /// Transfers `amount` of tokens from `from` to `to`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the transferring policy. + public fun transfer(from: &signer, to: address, amount: u64, _witness: CoinType) acquires Balance { + let from_addr = signer::address_of(from); + assert!(from_addr != to, EEQUAL_ADDR); + let check = withdraw(from_addr, amount); + deposit(to, check); + } + + spec transfer { + let addr_from = signer::address_of(from); + + let balance_from = global>(addr_from).coin.value; + let balance_to = global>(to).coin.value; + let post balance_from_post = global>(addr_from).coin.value; + let post balance_to_post = global>(to).coin.value; + + ensures balance_from_post == balance_from - amount; + ensures balance_to_post == balance_to + amount; + } + + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + spec withdraw { + let balance = global>(addr).coin.value; + + aborts_if !exists>(addr); + aborts_if balance < amount; + + let post balance_post = global>(addr).coin.value; + ensures result == Coin { value: amount }; + ensures balance_post == balance - amount; + } + + fun deposit(addr: address, check: Coin) acquires Balance{ + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } + + spec deposit { + let balance = global>(addr).coin.value; + let check_value = check.value; + + aborts_if !exists>(addr); + aborts_if balance + check_value > MAX_U64; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance + check_value; + } +} diff --git a/vendors/move/crates/documentation/tutorial/step_8_sol/BasicCoin/Move.toml b/vendors/move/crates/documentation/tutorial/step_8_sol/BasicCoin/Move.toml new file mode 100644 index 000000000..0b9d0240c --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_8_sol/BasicCoin/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "BasicCoin" +version = "0.0.0" + +[addresses] +NamedAddr = "0xDEADBEEF" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib/", addr_subst = { "std" = "0x1" } } diff --git a/vendors/move/crates/documentation/tutorial/step_8_sol/BasicCoin/sources/BasicCoin.move b/vendors/move/crates/documentation/tutorial/step_8_sol/BasicCoin/sources/BasicCoin.move new file mode 100644 index 000000000..921ffa36c --- /dev/null +++ b/vendors/move/crates/documentation/tutorial/step_8_sol/BasicCoin/sources/BasicCoin.move @@ -0,0 +1,137 @@ +/// This module defines a minimal and generic Coin and Balance. +module NamedAddr::BasicCoin { + use std::signer; + + /// Error codes + const ENOT_MODULE_OWNER: u64 = 0; + const EINSUFFICIENT_BALANCE: u64 = 1; + const EALREADY_HAS_BALANCE: u64 = 2; + const EALREADY_INITIALIZED: u64 = 3; + const EEQUAL_ADDR: u64 = 4; + + struct Coin has store { + value: u64 + } + + struct Balance has key { + coin: Coin + } + + public fun publish_balance(account: &signer) { + let empty_coin = Coin { value: 0 }; + assert!(!exists>(signer::address_of(account)), EALREADY_HAS_BALANCE); + move_to(account, Balance { coin: empty_coin }); + } + + spec publish_balance { + include Schema_publish {addr: signer::address_of(account), amount: 0}; + } + + spec schema Schema_publish { + addr: address; + amount: u64; + + aborts_if exists>(addr); + + ensures exists>(addr); + let post balance_post = global>(addr).coin.value; + + ensures balance_post == amount; + } + + /// Mint `amount` tokens to `mint_addr`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the minting policy. + public fun mint(mint_addr: address, amount: u64, _witness: CoinType) acquires Balance { + // Deposit `total_value` amount of tokens to mint_addr's balance + deposit(mint_addr, Coin { value: amount }); + } + + spec mint { + include DepositSchema {addr: mint_addr, amount}; + } + + public fun balance_of(owner: address): u64 acquires Balance { + borrow_global>(owner).coin.value + } + + spec balance_of { + pragma aborts_if_is_strict; + aborts_if !exists>(owner); + } + + /// Transfers `amount` of tokens from `from` to `to`. This method requires a witness with `CoinType` so that the + /// module that owns `CoinType` can decide the transferring policy. + public fun transfer(from: &signer, to: address, amount: u64, _witness: CoinType) acquires Balance { + let from_addr = signer::address_of(from); + assert!(from_addr != to, EEQUAL_ADDR); + let check = withdraw(from_addr, amount); + deposit(to, check); + } + + spec transfer { + let addr_from = signer::address_of(from); + + let balance_from = global>(addr_from).coin.value; + let balance_to = global>(to).coin.value; + let post balance_from_post = global>(addr_from).coin.value; + let post balance_to_post = global>(to).coin.value; + + aborts_if !exists>(addr_from); + aborts_if !exists>(to); + aborts_if balance_from < amount; + aborts_if balance_to + amount > MAX_U64; + aborts_if addr_from == to; + + ensures balance_from_post == balance_from - amount; + ensures balance_to_post == balance_to + amount; + } + + fun withdraw(addr: address, amount: u64) : Coin acquires Balance { + let balance = balance_of(addr); + assert!(balance >= amount, EINSUFFICIENT_BALANCE); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + *balance_ref = balance - amount; + Coin { value: amount } + } + + spec withdraw { + let balance = global>(addr).coin.value; + + aborts_if !exists>(addr); + aborts_if balance < amount; + + let post balance_post = global>(addr).coin.value; + ensures result == Coin { value: amount }; + ensures balance_post == balance - amount; + } + + fun deposit(addr: address, check: Coin) acquires Balance{ + let balance = balance_of(addr); + let balance_ref = &mut borrow_global_mut>(addr).coin.value; + let Coin { value } = check; + *balance_ref = balance + value; + } + + spec deposit { + let balance = global>(addr).coin.value; + let check_value = check.value; + + aborts_if !exists>(addr); + aborts_if balance + check_value > MAX_U64; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance + check_value; + } + + spec schema DepositSchema { + addr: address; + amount: u64; + let balance = global>(addr).coin.value; + + aborts_if !exists>(addr); + aborts_if balance + amount > MAX_U64; + + let post balance_post = global>(addr).coin.value; + ensures balance_post == balance + amount; + } +} diff --git a/vendors/move/crates/enum-compat-util/Cargo.toml b/vendors/move/crates/enum-compat-util/Cargo.toml new file mode 100644 index 000000000..ba897d410 --- /dev/null +++ b/vendors/move/crates/enum-compat-util/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "enum-compat-util" +version = "0.1.0" +authors = ["Mysten Labs "] +license = "Apache-2.0" +publish = false +edition = "2021" + +[dependencies] +serde_yaml.workspace = true diff --git a/vendors/move/crates/enum-compat-util/src/lib.rs b/vendors/move/crates/enum-compat-util/src/lib.rs new file mode 100644 index 000000000..f90be77a4 --- /dev/null +++ b/vendors/move/crates/enum-compat-util/src/lib.rs @@ -0,0 +1,48 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use std::io::Write; +use std::path::PathBuf; + +pub trait EnumOrderMap { + fn order_to_variant_map() -> std::collections::BTreeMap; +} + +pub fn check_enum_compat_order(snapshot_file: PathBuf) { + let new_map = T::order_to_variant_map(); + + if let Err(err) = std::fs::read_to_string(snapshot_file.clone()) { + if err.kind() == std::io::ErrorKind::NotFound { + // Create the file if not exists + std::fs::create_dir_all(snapshot_file.parent().unwrap()).unwrap(); + let mut file = std::fs::File::create(snapshot_file).unwrap(); + let content: String = serde_yaml::to_string(&new_map).unwrap(); + + write!(file, "{}", content).unwrap(); + return; + } + panic!("Error reading file: {:?}: err {:?}", snapshot_file, err); + } + + let existing_map: std::collections::BTreeMap = + serde_yaml::from_str(&std::fs::read_to_string(snapshot_file.clone()).unwrap()).unwrap(); + + // Check that the new map includes the existing map in order + for (pos, val) in existing_map { + match new_map.get(&pos) { + None => { + panic!("Enum variant {} has been removed. Not allowed: enum must be backward compatible.", val); + } + Some(new_val) if new_val == &val => continue, + Some(new_val) => { + panic!("Enum variant {val} has been swapped with {new_val} at position {pos}. Not allowed: enum must be backward compatible."); + } + } + } + + // Update the file + let mut file = std::fs::File::create(snapshot_file).unwrap(); + let content: String = serde_yaml::to_string(&new_map).unwrap(); + + write!(file, "{}", content).unwrap(); +} diff --git a/vendors/move/crates/evm/README.md b/vendors/move/crates/evm/README.md new file mode 100644 index 000000000..883e3bd88 --- /dev/null +++ b/vendors/move/crates/evm/README.md @@ -0,0 +1,15 @@ +# Move-on-EVM + +> NOTE: this tree contains an experimental version of Move which runs on the EVM. The programming model is +> different from regular Move. The examples in this directory do not work with the usual Move +> tools and blockchains. + +"Move-on-EVM" is a programming model in Move for EVM. In the current model, *each Move EVM contract has its own isolated address space*. This reflects the setup of the EVM most naturally, where storage between contracts cannot be shared apart from via accessor contract functions. Move EVM contracts use attributes to indicate the usage of structs for storage and events, and for functions to be callable from other contracts. It is expected that there is some codegen of Move from these attributes. For example, functions marked as `callable` have a generated API for cross-contract EVM call and delegate invocations. The module [Evm.move](./stdlib/sources/Evm.move) contains the API of a Move contract to the EVM. It encapsulates access to the transaction context and other EVM builtins + +This directory contains the following sub-directories: +- [move-to-yul](./move-to-yul) is a cross compiler that compiles Move contracts to the intermediate language Yul. +- [stdlib](./stdlib) is the standard library for Move-on-EVM. +- [examples](./examples) contains multiple Move-on-EVM examples including ERC20, ERC721 and ERC1155. +- [hardhat-examples](./hardhat-examples) is a Hardhat project to demonstrate Move-on-EVM. +- [hardhat-move](./hardhat-move) is a Hardhat plugin to support the Move language. +- [exec-utils](./exec-utils) contains EVM execution utils. diff --git a/vendors/move/crates/evm/examples/Move.toml b/vendors/move/crates/evm/examples/Move.toml new file mode 100644 index 000000000..2c513660c --- /dev/null +++ b/vendors/move/crates/evm/examples/Move.toml @@ -0,0 +1,12 @@ +[package] +name = "EvmExamples" +version = "1.5.0" + +[addresses] +std = "0x1" +Evm = "0x2" + +[dependencies] +MoveStdlib = { local = "../../move-stdlib" } +MoveNursery = { local = "../../move-stdlib/nursery" } +EvmStdlib = { local = "../stdlib" } diff --git a/vendors/move/crates/evm/examples/README.md b/vendors/move/crates/evm/examples/README.md new file mode 100644 index 000000000..1098286db --- /dev/null +++ b/vendors/move/crates/evm/examples/README.md @@ -0,0 +1,14 @@ +# Move-on-EVM Examples + +This directory contains (a growing set of) examples of "Move-on-EVM", a programming model in Move for EVM. + +- [Token.move](./sources/Token.move) contains an implementation of ERC20 which is intended to be compliant and callable + from other EVM code (Move or otherwise). +- [Faucet.move](./sources/Faucet.move) contains the faucet example from the Ethereum book. +- [ERC20.move](./sources/ERC20.move) contains another implementation of the ERC20 standard which uses a single `struct` to represent the contract state. +- [ERC165.move](./sources/ERC165.move) contains a sample implementation of the ERC165 standard. +- [ERC721.move](./sources/ERC721.move) contains an implementation of ERC721 which is the standard for non-fungible tokens. +- [ERC1155.move](./sources/ERC1155.move) contains an implementation of ERC1155 which is the standard for multi-tokens. +- [TestUniswap.move](./sources/TestUniswap.move) and [TestUniswapLiquidity.move](./sources/TestUniswapLiquidity.move) are the sample client modules of `Uniswap`. + +This directory is a Move package. To build the source files, use `move build`. Moreover, use `move test` to run the unit tests located in the `tests` directory. diff --git a/vendors/move/crates/evm/examples/sources/ERC1155.move b/vendors/move/crates/evm/examples/sources/ERC1155.move new file mode 100644 index 000000000..9395a888f --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/ERC1155.move @@ -0,0 +1,270 @@ +#[evm_contract] +/// An implementation of the ERC-1155 Multi Token Standard. +module Evm::ERC1155 { + use Evm::Evm::{sender, self, sign, emit, isContract}; + use Evm::IERC1155Receiver; + use Evm::IERC165; + use Evm::IERC1155; + use Evm::Table::{Self, Table}; + use Evm::Result; + use Evm::U256::{Self, U256}; + use std::ascii::{String}; + use std::errors; + use std::vector; + + #[event] + struct TransferSingle { + operator: address, + from: address, + to: address, + id: U256, + value: U256, + } + + #[event] + struct TransferBatch { + operator: address, + from: address, + to: address, + ids: vector, + values: vector, + } + + #[event] + struct ApprovalForAll { + owner: address, + operator: address, + approved: bool, + } + + #[event] + struct URI { + value: String, + id: U256, + } + + #[storage] + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + balances: Table>, + operatorApprovals: Table>, + uri: String, + owner: address, // Implements the "ownable" pattern. + } + + #[create] + /// Constructor of this contract. + public fun create(uri: String) { + // Initial state of contract + move_to( + &sign(self()), + State { + balances: Table::empty>(), + operatorApprovals: Table::empty>(), + uri, + owner: sender(), + } + ); + } + + #[callable, view] + /// Returns the name of the token + public fun uri(): String acquires State { + borrow_global(self()).uri + } + + #[callable, view] + /// Get the balance of an account's token. + public fun balanceOf(account: address, id: U256): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_balanceOf(s, id, account) + } + + #[callable, view] + /// Get the balance of multiple account/token pairs. + public fun balanceOfBatch(accounts: vector
, ids: vector): vector acquires State { + assert!(vector::length(&accounts) == vector::length(&ids), errors::invalid_argument(0)); + let len = vector::length(&accounts); + let i = 0; + let balances = vector::empty(); + while(i < len) { + vector::push_back( + &mut balances, + balanceOf( + *vector::borrow(&accounts, i), + *vector::borrow(&ids, i) + ) + ); + i = i + 1; + }; + balances + } + + #[callable, view] + /// Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. + public fun setApprovalForAll(operator: address, approved: bool) acquires State { + let s = borrow_global_mut(self()); + let operatorApproval = mut_operatorApprovals(s, sender(), operator); + *operatorApproval = approved; + emit(ApprovalForAll{owner: sender(), operator, approved}); + } + + #[callable, view] + /// Queries the approval status of an operator for a given owner. + public fun isApprovalForAll(account: address, operator: address): bool acquires State { + let s = borrow_global_mut(self()); + *mut_operatorApprovals(s, account, operator) + } + + #[callable] + /// Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + public fun safeTransferFrom(from: address, to: address, id: U256, amount: U256, _data: vector) acquires State { + assert!(from == sender() || isApprovalForAll(from, sender()), errors::invalid_argument(0)); + let s = borrow_global_mut(self()); + let mut_balance_from = mut_balanceOf(s, copy id, from); + assert!(U256::le(copy amount, *mut_balance_from), errors::invalid_argument(0)); + *mut_balance_from = U256::sub(*mut_balance_from, copy amount); + let mut_balance_to = mut_balanceOf(s, copy id, to); + *mut_balance_to = U256::add(*mut_balance_to, copy amount); + // TODO: Unit testing does not support events yet. + //let operator = sender(); + //emit(TransferSingle{operator, from, to, id: copy id, value: copy amount}); + // TODO: Unit testing does not support the following function. + //doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); + } + + #[callable] + /// Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + public fun safeBatchTransferFrom(from: address, to: address, ids: vector, amounts: vector, data: vector) acquires State { + assert!(from == sender() || isApprovalForAll(from, sender()), errors::invalid_argument(0)); + assert!(vector::length(&amounts) == vector::length(&ids), errors::invalid_argument(0)); + let len = vector::length(&amounts); + let i = 0; + + let operator = sender(); + let s = borrow_global_mut(self()); + + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_from = mut_balanceOf(s, copy id, from); + assert!(U256::le(copy amount, *mut_balance_from), errors::invalid_argument(0)); + *mut_balance_from = U256::sub(*mut_balance_from, copy amount); + let mut_balance_to = mut_balanceOf(s, id, to); + *mut_balance_to = U256::add(*mut_balance_to, amount); + + i = i + 1; + }; + + emit(TransferBatch{operator, from, to, ids: copy ids, values: copy amounts}); + + doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); + } + + #[callable] + // Query if this contract implements a certain interface. + public fun supportsInterface(interfaceId: vector): bool { + &interfaceId == &IERC1155::interfaceId() || &interfaceId == &IERC165::interfaceId() + } + + #[callable] + public fun owner(): address acquires State { + borrow_global_mut(self()).owner + } + + #[callable] + // Query if this contract implements a certain interface. + public fun mint(to: address, id: U256, amount: U256, _data: vector) acquires State { + assert!(sender() == owner(), errors::invalid_argument(0)); // Only owner can mint. + let s = borrow_global_mut(self()); + let mut_balance_to = mut_balanceOf(s, copy id, to); + *mut_balance_to = U256::add(*mut_balance_to, copy amount); + // TODO: Unit testing does not support events yet. + //emit(TransferSingle{operator: sender(), from: @0x0, to, id: copy id, value: copy amount}); + } + + #[callable] + // Query if this contract implements a certain interface. + public fun mintBatch(to: address, ids: vector, amounts: vector, _data: vector) acquires State { + assert!(sender() == owner(), errors::invalid_argument(0)); // Only owner can mint. + assert!(vector::length(&amounts) == vector::length(&ids), errors::invalid_argument(0)); + let len = vector::length(&amounts); + let i = 0; + + let s = borrow_global_mut(self()); + + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_to = mut_balanceOf(s, id, to); + *mut_balance_to = U256::add(*mut_balance_to, amount); + + i = i + 1; + }; + // TODO: Unit testing does not support events yet. + //emit(TransferBatch{operator: sender(), from: @0x0, to, ids: copy ids, values: copy amounts}); + } + + /// Helper function to return a mut ref to the operatorApproval + fun mut_operatorApprovals(s: &mut State, account: address, operator: address): &mut bool { + if(!Table::contains(&s.operatorApprovals, &account)) { + Table::insert( + &mut s.operatorApprovals, + &account, + Table::empty() + ) + }; + let operatorApproval_account = Table::borrow_mut( + &mut s.operatorApprovals, + &account + ); + Table::borrow_mut_with_default(operatorApproval_account, &operator, false) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, id: U256, account: address): &mut U256 { + if(!Table::contains(&s.balances, &id)) { + Table::insert( + &mut s.balances, + &id, + Table::empty() + ) + }; + let balances_id = Table::borrow_mut(&mut s.balances, &id); + Table::borrow_mut_with_default(balances_id, &account, U256::zero()) + } + + /// Helper function for the safe transfer acceptance check. + fun doSafeTransferAcceptanceCheck(operator: address, from: address, to: address, id: U256, amount: U256, data: vector) { + if (isContract(to)) { + let result = IERC1155Receiver::call_onERC1155Received(to, operator, from, id, amount, data); + if (Result::is_ok(&result)) { + let retval = Result::unwrap(result); + let expected = IERC1155Receiver::selector_onERC1155Received(); + assert!(retval == expected, errors::custom(0)); + } + else { + let _error = Result::unwrap_err(result); + abort(errors::custom(1)) // TODO: abort with the `_error` value. + } + } + } + + /// Helper function for the safe batch transfer acceptance check. + fun doSafeBatchTransferAcceptanceCheck(operator: address, from: address, to: address, ids: vector, amounts: vector, data: vector) { + if (isContract(to)) { + let result = IERC1155Receiver::call_onERC1155BatchReceived(to, operator, from, ids, amounts, data); + if (Result::is_ok(&result)) { + let retval = Result::unwrap(result); + let expected = IERC1155Receiver::selector_onERC1155BatchReceived(); + assert!(retval == expected, errors::custom(0)); + } + else { + let _error = Result::unwrap_err(result); + abort(errors::custom(1)) // TODO: abort with the `_error` value. + } + } + } +} diff --git a/vendors/move/crates/evm/examples/sources/ERC165.move b/vendors/move/crates/evm/examples/sources/ERC165.move new file mode 100644 index 000000000..274650423 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/ERC165.move @@ -0,0 +1,14 @@ +#[evm_contract] +/// An implementation of the ERC-165. +module Evm::ERC165 { + use Evm::IERC165; + use std::errors; + use std::vector; + + // Query if a contract implements an interface. + // The length of `interfaceId` is required to be 4. + public fun supportInterface(interfaceId: vector): bool { + assert!(vector::length(&interfaceId) == 4, errors::invalid_argument(0)); + (interfaceId == IERC165::selector_supportInterface()) + } +} diff --git a/vendors/move/crates/evm/examples/sources/ERC20.move b/vendors/move/crates/evm/examples/sources/ERC20.move new file mode 100644 index 000000000..58321e9b2 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/ERC20.move @@ -0,0 +1,160 @@ +#[evm_contract] +/// An implementation of the ERC-20 Token Standard. +module Evm::ERC20 { + use Evm::Evm::{sender, self, sign, emit}; + use Evm::Table::{Self, Table}; + use Evm::U256::{Self, U256}; + use std::ascii::{String}; + use std::errors; + + #[event] + struct Transfer { + from: address, + to: address, + value: U256, + } + + #[event] + struct Approval { + owner: address, + spender: address, + value: U256, + } + + #[storage] + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + balances: Table, + allowances: Table>, + total_supply: U256, + name: String, + symbol: String, + } + + #[create] + /// Constructor of this contract. + public fun create(name: String, symbol: String, initial_supply: U256) acquires State { + // Initial state of contract + move_to( + &sign(self()), + State { + total_supply: U256::zero(), + balances: Table::empty(), + allowances: Table::empty>(), + name, + symbol, + } + ); + // Minting the initial supply + mint(sender(), initial_supply); + } + + #[callable, view] + /// Returns the name of the token + public fun name(): String acquires State { + borrow_global(self()).name + } + + #[callable, view] + /// Returns the symbol of the token, usually a shorter version of the name. + public fun symbol(): String acquires State { + borrow_global(self()).symbol + } + + #[callable, view] + /// Returns the number of decimals used to get its user representation. + public fun decimals(): u8 { + 18 + } + + #[callable, view] + /// Returns the total supply of the token. + public fun totalSupply(): U256 acquires State { + borrow_global(self()).total_supply + } + + #[callable, view] + /// Returns the balance of an account. + public fun balanceOf(owner: address): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_balanceOf(s, owner) + } + + #[callable] + /// Transfers the amount from the sending account to the given account + public fun transfer(to: address, amount: U256): bool acquires State { + assert!(sender() != to, errors::invalid_argument(0)); + do_transfer(sender(), to, amount); + true + } + + #[callable] + /// Transfers the amount on behalf of the `from` account to the given account. + /// This evaluates and adjusts the allowance. + public fun transferFrom(from: address, to: address, amount: U256): bool acquires State { + assert!(sender() != to, errors::invalid_argument(0)); + let s = borrow_global_mut(self()); + let allowance_for_sender = mut_allowance(s, from, sender()); + assert!(U256::le(copy amount, *allowance_for_sender), errors::limit_exceeded(0)); + *allowance_for_sender = U256::sub(*allowance_for_sender, copy amount); + do_transfer(from, to, amount); + true + } + + #[callable] + /// Approves that the spender can spent the given amount on behalf of the calling account. + public fun approve(spender: address, amount: U256): bool acquires State { + let s = borrow_global_mut(self()); + if(!Table::contains(&s.allowances, &sender())) { + Table::insert(&mut s.allowances, &sender(), Table::empty()) + }; + let a = Table::borrow_mut(&mut s.allowances, &sender()); + Table::insert(a, &spender, copy amount); + emit(Approval{owner: sender(), spender, value: amount}); + true + } + + #[callable, view] + /// Returns the allowance an account owner has approved for the given spender. + public fun allowance(owner: address, spender: address): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_allowance(s, owner, spender) + } + + /// Helper function to perform a transfer of funds. + fun do_transfer(from: address, to: address, amount: U256) acquires State { + let s = borrow_global_mut(self()); + let from_bal = mut_balanceOf(s, from); + assert!(U256::le(copy amount, *from_bal), errors::limit_exceeded(0)); + *from_bal = U256::sub(*from_bal, copy amount); + let to_bal = mut_balanceOf(s, to); + *to_bal = U256::add(*to_bal, copy amount); + // TODO: Unit testing does not support events yet. + //emit(Transfer{from, to, value: amount}); + } + + /// Helper function to return a mut ref to the allowance of a spender. + fun mut_allowance(s: &mut State, owner: address, spender: address): &mut U256 { + if(!Table::contains(&s.allowances, &owner)) { + Table::insert(&mut s.allowances, &owner, Table::empty()) + }; + let allowance_owner = Table::borrow_mut(&mut s.allowances, &owner); + Table::borrow_mut_with_default(allowance_owner, &spender, U256::zero()) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, owner: address): &mut U256 { + Table::borrow_mut_with_default(&mut s.balances, &owner, U256::zero()) + } + + /// Create `amount` tokens and assigns them to `account`, increasing + /// the total supply. + fun mint(account: address, amount: U256) acquires State { + let s = borrow_global_mut(self()); + s.total_supply = U256::add(s.total_supply, amount); + let mut_bal_account = mut_balanceOf(s, account); + *mut_bal_account = U256::add(*mut_bal_account, amount); + // TODO: Unit testing does not support events yet. + //emit(Transfer{from: @0x0, to: account, value: amount}); + } +} diff --git a/vendors/move/crates/evm/examples/sources/ERC721.move b/vendors/move/crates/evm/examples/sources/ERC721.move new file mode 100644 index 000000000..1d1fdf3b8 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/ERC721.move @@ -0,0 +1,246 @@ +#[evm_contract] +/// An implementation of the ERC-721 Non-Fungible Token Standard. +module Evm::ERC721 { + use Evm::Evm::{sender, self, sign, emit, isContract, tokenURI_with_baseURI}; + use Evm::Result; + use Evm::IERC721Receiver; + use Evm::IERC721Metadata; + use Evm::IERC721; + use Evm::IERC165; + use Evm::Table::{Self, Table}; + use Evm::U256::{Self, U256}; + use std::ascii::{Self, String}; + use std::errors; + use std::vector; + + #[event] + struct Transfer { + from: address, + to: address, + tokenId: U256, + } + + #[event] + struct Approval { + owner: address, + approved: address, + tokenId: U256, + } + + #[event] + struct ApprovalForAll { + owner: address, + operator: address, + approved: bool, + } + + #[storage] + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + name: String, + symbol: String, + owners: Table, + balances: Table, + tokenApprovals: Table, + operatorApprovals: Table>, + } + + #[create] + /// Constructor of this contract. + public fun create(name: String, symbol: String) { + // Initial state of contract + move_to( + &sign(self()), + State { + name, + symbol, + owners: Table::empty(), + balances: Table::empty(), + tokenApprovals: Table::empty(), + operatorApprovals: Table::empty>(), + } + ); + } + + #[callable] + // Query if this contract implements a certain interface. + public fun supportsInterface(interfaceId: vector): bool { + &interfaceId == &IERC721::interfaceId() || + &interfaceId == &IERC721Metadata::interfaceId() || + &interfaceId == &IERC165::interfaceId() + } + + #[callable] + /// Get the name. + public fun name(): String acquires State { + let s = borrow_global(self()); + s.name + } + + #[callable] + /// Get the symbol. + public fun symbol(): String acquires State { + let s = borrow_global(self()); + s.symbol + } + + #[callable] + /// Get the name. + public fun tokenURI(tokenId: U256): String { + let baseURI = b""; // TODO: Implement this. + ascii::string(tokenURI_with_baseURI(baseURI, tokenId)) + } + + #[callable] + /// Count all NFTs assigned to an owner. + public fun balanceOf(owner: address): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_balanceOf(s, owner) + } + + #[callable] + /// Find the owner of an NFT. + public fun ownerOf(tokenId: U256): address acquires State { + let s = borrow_global_mut(self()); + *mut_ownerOf(s, tokenId) + } + + #[callable(name=safeTransferFrom)] // Overloading `safeTransferFrom` + /// Transfers the ownership of an NFT from one address to another address. + public fun safeTransferFrom_with_data(from: address, to: address, tokenId: U256, data: vector) acquires State { + transferFrom(from, to, copy tokenId); + doSafeTransferAcceptanceCheck(from, to, tokenId, data); + + } + + #[callable] + /// Transfers the ownership of an NFT from one address to another address. + public fun safeTransferFrom(from: address, to: address, tokenId: U256) acquires State { + safeTransferFrom_with_data(from, to, tokenId, b""); + } + + #[callable] + /// Transfer ownership of an NFT. THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + public fun transferFrom(from: address, to: address, tokenId: U256) acquires State { + assert!(isApprovedOrOwner(sender(), copy tokenId), errors::invalid_argument(0)); + assert!(ownerOf(copy tokenId) == from, errors::invalid_argument(0)); + assert!(to != @0x0, errors::invalid_argument(0)); + + // Clear approvals from the previous owner + approve(@0x0, copy tokenId); + + let s = borrow_global_mut(self()); + + let mut_balance_from = mut_balanceOf(s, from); + *mut_balance_from = U256::sub(*mut_balance_from, U256::one()); + + let mut_balance_to = mut_balanceOf(s, to); + *mut_balance_to = U256::add(*mut_balance_to, U256::one()); + + let mut_owner_token = mut_ownerOf(s, copy tokenId); + *mut_owner_token = to; + + emit(Transfer{from, to, tokenId}); + } + + #[callable] + /// Change or reaffirm the approved address for an NFT. + public fun approve(approved: address, tokenId: U256) acquires State { + let owner = ownerOf(copy tokenId); + assert!(owner != @0x0, errors::invalid_argument(0)); + assert!(approved != owner, errors::invalid_argument(0)); + assert!(sender() == owner || isApprovedForAll(owner, sender()), errors::invalid_argument(0)); + + let s = borrow_global_mut(self()); + *mut_tokenApproval(s, copy tokenId) = approved; + emit(Approval{ owner, approved, tokenId}) + } + + #[callable] + /// Enable or disable approval for a third party ("operator") to manage + /// all of the sender's assets. + public fun setApprovalForAll(operator: address, approved: bool) acquires State { + let s = borrow_global_mut(self()); + *mut_operatorApproval(s, sender(), operator) = approved; + } + + #[callable] + /// Get the approved address for a single NFT. + public fun getApproved(tokenId: U256): address acquires State { + let s = borrow_global_mut(self()); + assert!(tokenExists(s, copy tokenId), errors::invalid_argument(0)); + *mut_tokenApproval(s, tokenId) + } + + #[callable] + /// Query if an address is an authorized operator for another address. + public fun isApprovedForAll(owner: address, operator: address): bool acquires State { + let s = borrow_global_mut(self()); + *mut_operatorApproval(s, owner, operator) + } + + /// Helper function to return true iff `spender` is the owner or an approved one for `tokenId`. + fun isApprovedOrOwner(spender: address, tokenId: U256): bool acquires State { + let s = borrow_global_mut(self()); + assert!(tokenExists(s, copy tokenId), errors::invalid_argument(0)); + let owner = ownerOf(copy tokenId); + return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, owner: address): &mut U256 { + Table::borrow_mut_with_default(&mut s.balances, &owner, U256::zero()) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_ownerOf(s: &mut State, tokenId: U256): &mut address { + Table::borrow_mut_with_default(&mut s.owners, &tokenId, @0x0) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_tokenApproval(s: &mut State, tokenId: U256): &mut address { + Table::borrow_mut_with_default(&mut s.tokenApprovals, &tokenId, @0x0) + } + + /// Helper function to return a mut ref to the operator approval. + fun mut_operatorApproval(s: &mut State, owner: address, operator: address): &mut bool { + if(!Table::contains(&s.operatorApprovals, &owner)) { + Table::insert( + &mut s.operatorApprovals, + &owner, + Table::empty() + ) + }; + let approvals = Table::borrow_mut(&mut s.operatorApprovals, &owner); + Table::borrow_mut_with_default(approvals, &operator, false) + } + + /// Helper function to return true iff the token exists. + fun tokenExists(s: &mut State, tokenId: U256): bool { + let mut_ownerOf_tokenId = mut_ownerOf(s, tokenId); + *mut_ownerOf_tokenId != @0x0 + } + + /// Helper function for the acceptance check. + fun doSafeTransferAcceptanceCheck(from: address, to: address, tokenId: U256, data: vector) { + if (isContract(to)) { + let result = IERC721Receiver::try_call_onERC721Received(to, sender(), from, tokenId, data); + if (Result::is_ok(&result)) { + let retval = Result::unwrap(result); + let expected = IERC721Receiver::selector_onERC721Received(); + assert!(retval == expected, errors::custom(0)); + } + else { + let error_reason = Result::unwrap_err(result); + if(vector::length(&error_reason) == 0) { + abort(errors::custom(1)) // ERC721: transfer to non ERC721Receiver implementer + } + else { + abort(errors::custom(2)) // TODO: abort with the `_error` value. + } + } + } + } +} diff --git a/vendors/move/crates/evm/examples/sources/Faucet.move b/vendors/move/crates/evm/examples/sources/Faucet.move new file mode 100644 index 000000000..fc4b2c0eb --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/Faucet.move @@ -0,0 +1,58 @@ +#[evm_contract] +/// Faucet example in the Ethereum book. +module 0x42::Faucet { + use Evm::Evm::{sender, value, self, sign, balance, transfer, emit}; + use Evm::U256::{Self, U256}; + use std::errors; + + #[storage] + struct State has key { + owner: address, + } + + #[event] + struct WithdrawalEvent { + to: address, + amount: U256 + } + + #[event] + struct DepositEvent { + from: address, + amount: U256 + } + + #[create] + public fun create() { + move_to(&sign(self()), State{owner: sender()}) + } + + #[delete] + public fun delete() acquires State { + let state = borrow_global(self()); + assert!(sender() == state.owner, errors::requires_address(0)); + } + + #[receive, payable] + public fun receive() { + emit(DepositEvent{from: sender(), amount: value()}) + } + + #[callable] + public fun withdraw(amount: U256) acquires State { + let state = borrow_global(self()); + + // Don't allow to withdraw from self. + assert!(state.owner != self(), errors::invalid_argument(0)); + + // Limit withdrawal amount + assert!(U256::le(copy amount, U256::u256_from_u128(100)), errors::invalid_argument(0)); + + // Funds must be available. + assert!(U256::le(copy amount, balance(self())), errors::limit_exceeded(0)); + + // Transfer funds + transfer(sender(), copy amount); + emit(WithdrawalEvent{to: sender(), amount}) + } +} diff --git a/vendors/move/crates/evm/examples/sources/IERC1155.move b/vendors/move/crates/evm/examples/sources/IERC1155.move new file mode 100644 index 000000000..320bfc27b --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IERC1155.move @@ -0,0 +1,13 @@ +#[interface] +/// The interface for ERC-1155. +/// This module defines the API for the interface of ERC-1155 and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IERC1155 { + + #[interface_id] + /// Return the interface identifier. + // TODO: complete this function. + public native fun interfaceId(): vector; + + // TODO: complete this module. +} diff --git a/vendors/move/crates/evm/examples/sources/IERC1155Receiver.move b/vendors/move/crates/evm/examples/sources/IERC1155Receiver.move new file mode 100644 index 000000000..05bf35590 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IERC1155Receiver.move @@ -0,0 +1,36 @@ +#[interface] +/// The interface for ERC-721 Token Receiver. +/// This module defines the API for the interface of ERC-721 Token Receiver and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IERC1155Receiver { + use Evm::Evm::{keccak256, bytes4, bytes_xor}; + use Evm::Result::{Result}; + use Evm::U256::{U256}; + + #[external] + public native fun call_onERC1155Received(contract: address, operator: address, from: address, id: U256, amount: U256, bytes: vector): Result, vector>; + + #[external] + public native fun call_onERC1155BatchReceived(contract: address, operator: address, from: address, ids: vector, amounts: vector, bytes: vector): Result, vector>; + + #[selector] + /// Return the selector of the function `onERC1155Received` + public fun selector_onERC1155Received(): vector { + bytes4(keccak256(b"onERC1155Received(address,address,uint256,uint256,bytes)")) + } + + #[selector] + /// Return the selector of the function `onERC1155Received` + public fun selector_onERC1155BatchReceived(): vector { + bytes4(keccak256(b"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) + } + + #[interface_id] + /// Return the interface identifier of this interface. + public fun interfaceId(): vector { + bytes_xor( + selector_onERC1155Received(), + selector_onERC1155BatchReceived() + ) + } +} diff --git a/vendors/move/crates/evm/examples/sources/IERC165.move b/vendors/move/crates/evm/examples/sources/IERC165.move new file mode 100644 index 000000000..c1390602e --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IERC165.move @@ -0,0 +1,28 @@ +#[interface] +/// The interface for the ERC-165. +/// This module defines the API for the interface of ERC-165 and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IERC165 { + use Evm::Evm::{keccak256, bytes4}; + use Evm::Result::{Result}; + + #[external] + public native fun call_supportInterface(contract: address, interfaceId: vector): Result>; + + #[selector] + public fun selector_supportInterface(): vector { + bytes4(keccak256(b"supportInterface(bytes4)")) + } + + #[interface_id] + /// Return the interface identifier. This function corresponds to + /// `type(I).interfaceId` in Solidity where `I` is an interface. + // The following is a excerpt from the Solidity documentation: + // A bytes4 value containing the EIP-165 interface identifier of + // the given interface I. This identifier is defined as the XOR + // of all function selectors defined within the interface itself + // - excluding all inherited functions. + public fun interfaceId(): vector { + selector_supportInterface() + } +} diff --git a/vendors/move/crates/evm/examples/sources/IERC20.move b/vendors/move/crates/evm/examples/sources/IERC20.move new file mode 100644 index 000000000..77bb95bd1 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IERC20.move @@ -0,0 +1,23 @@ +#[interface] +/// The interface for ERC-20. +/// This module defines the API for the interface of ERC-20 and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IERC20 { + use Evm::U256::{U256}; + + #[external(sig=b"transferFrom(address,address,uint) returns (bool)")] + public native fun call_transferFrom(contract: address, from: address, to: address, amount: U256): bool; + + #[external(sig=b"approve(address,uint) returns (bool)")] + public native fun call_approve(contract: address, spender: address, amount: U256): bool; + + #[external(sig=b"balanceOf(address) returns (uint)")] + public native fun call_balanceOf(contract: address, account: address): U256; + + #[interface_id] + /// Return the interface identifier. + // TODO: complete this function. + public native fun interfaceId(): vector; + + // TODO: complete this module. +} diff --git a/vendors/move/crates/evm/examples/sources/IERC721.move b/vendors/move/crates/evm/examples/sources/IERC721.move new file mode 100644 index 000000000..c150a02fc --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IERC721.move @@ -0,0 +1,22 @@ +#[interface] +/// The interface for ERC-721. +/// This module defines the API for the interface of ERC-721 and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IERC721 { + use Evm::Evm::{Unit}; + use Evm::Result::{Result}; + use Evm::U256::{U256}; + + #[external] + public native fun call_safeTransferFrom(contract: address, from: address, to: address, tokenId: U256): Result>; + + #[external(name=safeTransferFrom)] + public native fun call_safeTransferFrom_with_data(contract: address, from: address, to: address, tokenId: U256, data: vector): Result>; + + #[interface_id] + /// Return the interface identifier. + // TODO: complete this function. + public native fun interfaceId(): vector; + + // TODO: complete this module. +} diff --git a/vendors/move/crates/evm/examples/sources/IERC721Metadata.move b/vendors/move/crates/evm/examples/sources/IERC721Metadata.move new file mode 100644 index 000000000..311eaf081 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IERC721Metadata.move @@ -0,0 +1,46 @@ +#[interface] +/// The interface for ERC-721 Metadata. +/// This module defines the API for the interface of ERC-721 Metadata and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IERC721Metadata { + use Evm::Evm::{bytes_xor, bytes4, keccak256}; + use Evm::Result::{Result}; + use std::ascii::{String}; + use Evm::U256::{U256}; + + #[external] + public native fun call_name(contract: address): Result>; + + #[external] + public native fun call_symbol(contract: address): Result>; + + #[external] + public native fun call_tokenURI(contract: address, tokenId: U256): Result>; + + #[selector] + public fun selector_name(): vector { + bytes4(keccak256(b"name()")) + } + + #[selector] + public fun selector_symbol(): vector { + bytes4(keccak256(b"symbol()")) + } + + #[selector] + public fun selector_tokenURI(): vector { + bytes4(keccak256(b"tokenURI(uint256)")) + } + + #[interface_id] + /// Return the interface identifier. + public fun interfaceId(): vector { + bytes_xor( + bytes_xor( + selector_name(), + selector_symbol() + ), + selector_tokenURI() + ) + } +} diff --git a/vendors/move/crates/evm/examples/sources/IERC721Receiver.move b/vendors/move/crates/evm/examples/sources/IERC721Receiver.move new file mode 100644 index 000000000..aaea8c477 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IERC721Receiver.move @@ -0,0 +1,27 @@ +#[interface] +/// The interface for ERC-721 Token Receiver. +/// This module defines the API for the interface of ERC-721 Token Receiver and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IERC721Receiver { + use Evm::Evm::{keccak256, bytes4}; + use Evm::Result::{Result}; + use Evm::U256::{U256}; + + #[external] + public native fun call_onERC721Received(contract: address, operator: address, from: address, tokenId: U256, bytes: vector): vector; + + #[external] + public native fun try_call_onERC721Received(contract: address, operator: address, from: address, tokenId: U256, bytes: vector): Result, vector>; + + #[selector] + /// Return the selector of the function `onERC721Received` + public fun selector_onERC721Received(): vector { + bytes4(keccak256(b"onERC721Received(address,address,uint256,bytes)")) + } + + #[interface_id] + /// Return the interface identifier for this interface. + public fun interfaceId(): vector { + selector_onERC721Received() + } +} diff --git a/vendors/move/crates/evm/examples/sources/IUniswapV2Factory.move b/vendors/move/crates/evm/examples/sources/IUniswapV2Factory.move new file mode 100644 index 000000000..28ceb1ebc --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IUniswapV2Factory.move @@ -0,0 +1,16 @@ +#[interface] +/// The interface for UniswapV2Factory. +/// This module defines the API for the interface of UniswapV2Factory and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IUniswapV2Factory { + + #[external(sig=b"getPair(address,address) returns (address)")] + public native fun call_getPair(contract: address, tokenA: address, tokenB: address): address; + + #[interface_id] + /// Return the interface identifier. + // TODO: complete this function. + public native fun interfaceId(): vector; + + // TODO: complete this module. +} diff --git a/vendors/move/crates/evm/examples/sources/IUniswapV2Router.move b/vendors/move/crates/evm/examples/sources/IUniswapV2Router.move new file mode 100644 index 000000000..a2180d571 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/IUniswapV2Router.move @@ -0,0 +1,23 @@ +#[interface] +/// The interface for UniswapV2Router. +/// This module defines the API for the interface of UniswapV2Router and +/// the utility functions such as selectors and `interfaceId`. +module Evm::IUniswapV2Router { + use Evm::U256::{U256}; + + #[external(sig=b"swapExactTokensForTokens(uint,uint,address[],address,uint) returns (uint[])")] + public native fun call_swapExactTokensForTokens(contract: address, amountIn: U256, amountOutMin: U256, path: vector
, to: address, deadline: U256): vector; + + #[external(sig=b"addLiquidity(address,address,uint,uint,uint,uint,address) returns (uint,uint,uint)")] + public native fun call_addLiquidity(contract: address, tokenA: address, tokenB: address, amountADesired: U256, amountBDesired: U256, amountAMin: U256, amountBMin: U256, to: address, deadline: U256): (U256, U256, U256); + + #[external(sig=b"removeLiquidity(address,address,uint,uint,uint,address,uint) returns (uint,uint)")] + public native fun call_removeLiquidity(contract: address, tokenA: address, tokenB: address, liquidity: U256, amountAMin: U256, amountBMin: U256, to: address, deadline: U256): (U256, U256); + + #[interface_id] + /// Return the interface identifier. + // TODO: complete this function. + public native fun interfaceId(): vector; + + // TODO: complete this module. +} diff --git a/vendors/move/crates/evm/examples/sources/TestUniswap.move b/vendors/move/crates/evm/examples/sources/TestUniswap.move new file mode 100644 index 000000000..b35ae4ea4 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/TestUniswap.move @@ -0,0 +1,48 @@ +// This module is to test the interaction with the existing dapp called UniswapV2. +module Evm::TestUniswap { + use Evm::IERC20; + use Evm::IUniswapV2Router; + use Evm::U256::{Self, U256, u256_from_words}; + use Evm::Evm::{sender, self, block_timestamp}; + use std::vector; + + // Swap tokenIn for tokenOut. + public fun swap( + tokenIn: address, + tokenOut: address, + amountIn: U256, + amountOutMin: U256, + to: address + ) { + // TODO: Replace these local constants with module-level constants once Move supports 20-bytes addresses and literals. + let const_UNISWAP_V2_ROUTER = U256::to_address(u256_from_words(0x7a250d56, 0x30B4cF539739dF2C5dAcb4c659F2488D)); + let const_WETH = U256::to_address(u256_from_words(0xC02aaA39, 0xb223FE8D0A0e5C4F27eAD9083C756Cc2)); + + IERC20::call_transferFrom(tokenIn, sender(), self(), copy amountIn); + IERC20::call_approve(tokenIn, const_UNISWAP_V2_ROUTER, copy amountIn); + + let path = vector::empty
(); + + if(tokenIn == const_WETH || tokenOut == const_WETH) { + // Directly swapping tokenIn for tokenOut. + vector::push_back(&mut path, tokenIn); + vector::push_back(&mut path, tokenOut); + } + else { + // Swapping tokenIn for WETH, and then WETH for tokenOut. + // Bridging is needed because UniswapV2 cannot directly swap two ERC20 token types. + vector::push_back(&mut path, tokenIn); + vector::push_back(&mut path, const_WETH); + vector::push_back(&mut path, tokenOut); + }; + + IUniswapV2Router::call_swapExactTokensForTokens( + const_UNISWAP_V2_ROUTER, + amountIn, + amountOutMin, + path, + to, + block_timestamp() + ); + } +} diff --git a/vendors/move/crates/evm/examples/sources/TestUniswapLiquidity.move b/vendors/move/crates/evm/examples/sources/TestUniswapLiquidity.move new file mode 100644 index 000000000..35c189755 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/TestUniswapLiquidity.move @@ -0,0 +1,61 @@ +// This module is to test the interaction with the existing dapp called UniswapV2. +module Evm::TestUniswapLiquidity { + use Evm::IERC20; + use Evm::IUniswapV2Router; + use Evm::IUniswapV2Factory; + use Evm::U256::{Self, U256, u256_from_words}; + use Evm::Evm::{sender, self, block_timestamp}; + + public fun addLiquidity( + tokenA: address, + tokenB: address, + amountA: U256, + amountB: U256, + ) { + // TODO: Replace these local constants with module-level constants once Move supports 20-bytes addresses and literals. + let const_ROUTER = U256::to_address(u256_from_words(0x7a250d56, 0x30B4cF539739dF2C5dAcb4c659F2488D)); + + IERC20::call_transferFrom(tokenA, sender(), self(), copy amountA); + IERC20::call_transferFrom(tokenB, sender(), self(), copy amountB); + + IERC20::call_approve(tokenA, const_ROUTER, copy amountA); + IERC20::call_approve(tokenB, const_ROUTER, copy amountB); + + let (_amountA, _amountB, _liquidity) = IUniswapV2Router::call_addLiquidity( + const_ROUTER, + tokenA, + tokenB, + amountA, + amountB, + U256::one(), + U256::one(), + self(), + block_timestamp() + ); + } + + public fun removeLiquidity( + tokenA: address, + tokenB: address, + ) { + // TODO: Replace these local constants with module-level constants once Move supports 20-bytes addresses and literals. + let const_FACTORY = U256::to_address(u256_from_words(0x5C69bEe7, 0x01ef814a2B6a3EDD4B1652CB9cc5aA6f)); + let const_ROUTER = U256::to_address(u256_from_words(0x7a250d56, 0x30B4cF539739dF2C5dAcb4c659F2488D)); + + let pair = IUniswapV2Factory::call_getPair(const_FACTORY, tokenA, tokenB); + + let liquidity = IERC20::call_balanceOf(pair, self()); + IERC20::call_approve(pair, const_ROUTER, copy liquidity); + + let (_amountA, _amountB) = IUniswapV2Router::call_removeLiquidity( + const_ROUTER, + tokenA, + tokenB, + liquidity, + U256::one(), + U256::one(), + self(), + block_timestamp() + ); + } +} diff --git a/vendors/move/crates/evm/examples/sources/Token.move b/vendors/move/crates/evm/examples/sources/Token.move new file mode 100644 index 000000000..3805e1b95 --- /dev/null +++ b/vendors/move/crates/evm/examples/sources/Token.move @@ -0,0 +1,145 @@ +#[evm_contract] +/// An implementation of ERC20. +module Evm::ERC20Token { + use Evm::Evm::{sender, self, sign}; + use std::errors; + use std::vector; + + #[storage] + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + decimals: u8, + total_supply: u128, + } + + #[storage] + /// Represents the state of an account managed by this contract, located at + /// `borrow_global(address)`. Notice that the storage of this resource + /// is private to this contract, as each EVM contract manages its own Move address space. + struct Account has key { + /// The balance value. + value: u128, + /// The allowances this account has granted to other specified accounts. + allowances: vector + } + + /// How much a spender is allowed to use. + struct Allowance has store { + spender: address, + amount: u128, + } + + #[create] + /// Constructor of this contract. + public fun create(initial_amount: u128, decimals: u8) { + // Initial state of contract + move_to(&sign(self()), State{decimals, total_supply: initial_amount}); + + // Initialize senders balance with initial amount + move_to(&sign(sender()), Account{value: initial_amount, allowances: vector::empty()}); + } + + #[callable, view] + /// Returns the total supply of the token. + public fun total_supply(): u128 acquires State { + borrow_global(self()).total_supply + } + + #[callable, view] + /// Returns the balance of an account. + public fun balance_of(owner: address): u128 acquires Account { + borrow_global(owner).value + } + + #[callable, view] + /// Returns the allowance an account owner has approved for the given spender. + public fun allowance(owner: address, spender: address): u128 acquires Account { + let allowances = &borrow_global(owner).allowances; + let i = index_of_allowance(allowances, spender); + if (i < vector::length(allowances)) { + vector::borrow(allowances, i).amount + } else { + 0 + } + } + + #[callable] + /// Approves that the spender can spent the given amount on behalf of the calling account. + public fun approve(spender: address, amount: u128) acquires Account { + create_account_if_not_present(sender()); + let allowances = &mut borrow_global_mut(sender()).allowances; + mut_allowance(allowances, spender).amount = amount + } + + #[callable] + /// Transfers the amount from the sending account to the given account + public fun transfer(to: address, amount: u128) acquires Account { + assert!(sender() != to, errors::invalid_argument(0)); + do_transfer(sender(), to, amount) + } + + + #[callable] + /// Transfers the amount on behalf of the `from` account to the given account. + /// This evaluates and adjusts the allowance. + public fun transfer_from(from: address, to: address, amount: u128) acquires Account { + let allowances = &mut borrow_global_mut(from).allowances; + let allowance = mut_allowance(allowances, sender()); + assert!(allowance.amount >= amount, errors::limit_exceeded(0)); + allowance.amount = allowance.amount - amount; + do_transfer(from, to, amount) + } + + /// Helper function to perform a transfer of funds. + fun do_transfer(from: address, to: address, amount: u128) acquires Account { + create_account_if_not_present(from); + create_account_if_not_present(to); + let from_acc = borrow_global_mut(from); + assert!(from_acc.value >= amount, errors::limit_exceeded(0)); + from_acc.value = from_acc.value - amount; + let to_acc = borrow_global_mut(to); + to_acc.value = to_acc.value + amount; + } + + /// Helper function to find the index of an existing allowance. Returns length of the passed + /// vector if not present. + fun index_of_allowance(allowances: &vector, spender: address): u64 { + let i = 0; + let l = vector::length(allowances); + while (i < l) { + if (vector::borrow(allowances, i).spender == spender) { + return i + }; + i = i + 1; + }; + return l + } + + /// Helper function to return a mut ref to the allowance of a spender. + fun mut_allowance(allowances: &mut vector, spender: address): &mut Allowance { + let i = index_of_allowance(allowances, spender); + if (i == vector::length(allowances)) { + vector::push_back(allowances, Allowance{spender, amount: 0}) + }; + vector::borrow_mut(allowances, i) + } + + /// Helper function to create an account with a zero balance and no allowances. + fun create_account_if_not_present(owner: address) { + if (!exists(owner)) { + move_to(&sign(owner), Account{value: 0, allowances: vector::empty()}) + } + } + + // ============================================================================================================== + // The following APIs will be automatically generated from the #[callable] function attributes. They + // constitute the EVM level contract API. + + public native fun call_total_supply(contract: address): u128; + public native fun call_allowance(contract: address, owner: address, spender: address): u128; + public native fun call_approve(contract: address, spender: address, amount: u128); + public native fun call_transfer(contract: address, to: address, amount: u128); + public native fun call_transfer_from(contract: address, from: address, to: address, amount: u128); + + // ... and the same as delegate_XXXX APIs? +} diff --git a/vendors/move/crates/evm/examples/tests/ERC1155Tests.move b/vendors/move/crates/evm/examples/tests/ERC1155Tests.move new file mode 100644 index 000000000..267b3cc42 --- /dev/null +++ b/vendors/move/crates/evm/examples/tests/ERC1155Tests.move @@ -0,0 +1,81 @@ +module Evm::ERC1155Tests { + use Evm::Evm::sender; + use Evm::U256::{zero, one, u256_from_u128}; + use std::vector; + use Evm::ERC1155; + use std::ascii::{string}; + + const Alice: address = @0x8877; + const Bob: address = @0x8888; + + #[test] + fun test_create() { + ERC1155::create(string(vector::empty())); + } + + #[test] + fun test_balance_of() { + ERC1155::create(string(vector::empty())); + let id1 = one(); + let id2 = u256_from_u128(22); + assert!(ERC1155::balanceOf(sender(), id1) == zero(), 100); + assert!(ERC1155::balanceOf(sender(), id2) == zero(), 101); + assert!(ERC1155::balanceOf(Alice, id1) == zero(), 102); + assert!(ERC1155::balanceOf(Alice, id2) == zero(), 103); + assert!(ERC1155::balanceOf(Bob, id1) == zero(), 104); + assert!(ERC1155::balanceOf(Bob, id2) == zero(), 105); + } + + #[test] + fun test_mint() { + ERC1155::create(string(vector::empty())); + + let id1 = one(); + let id2 = u256_from_u128(22); + let dummy_data = vector::empty(); + + ERC1155::mint(Alice, id1, u256_from_u128(100), copy dummy_data); + ERC1155::mint(Bob, id2, u256_from_u128(1000), copy dummy_data); + + assert!(ERC1155::balanceOf(sender(), id1) == zero(), 106); + assert!(ERC1155::balanceOf(sender(), id2) == zero(), 107); + assert!(ERC1155::balanceOf(Alice, id1) == u256_from_u128(100), 108); + assert!(ERC1155::balanceOf(Alice, id2) == zero(), 109); + assert!(ERC1155::balanceOf(Bob, id1) == zero(), 110); + assert!(ERC1155::balanceOf(Bob, id2) == u256_from_u128(1000), 111); + } + + #[test] + #[expected_failure(abort_code = 124)] + fun test_transfer() { + ERC1155::create(string(vector::empty())); + + let id1 = one(); + let id2 = u256_from_u128(22); + let dummy_data = vector::empty(); + + ERC1155::mint(sender(), id1, u256_from_u128(100), copy dummy_data); + ERC1155::mint(sender(), id2, u256_from_u128(1000), copy dummy_data); + + assert!(ERC1155::balanceOf(sender(), id1) == u256_from_u128(100), 112); + assert!(ERC1155::balanceOf(sender(), id2) == u256_from_u128(1000), 113); + assert!(ERC1155::balanceOf(Alice, id1) == zero(), 114); + assert!(ERC1155::balanceOf(Alice, id2) == zero(), 115); + assert!(ERC1155::balanceOf(Bob, id1) == zero(), 116); + assert!(ERC1155::balanceOf(Bob, id2) == zero(), 117); + + ERC1155::safeTransferFrom(sender(), Alice, id1, u256_from_u128(20), copy dummy_data); + ERC1155::safeTransferFrom(sender(), Bob, id1, u256_from_u128(50), copy dummy_data); + ERC1155::safeTransferFrom(sender(), Alice, id2, u256_from_u128(300), copy dummy_data); + ERC1155::safeTransferFrom(sender(), Bob, id2, u256_from_u128(200), copy dummy_data); + + assert!(ERC1155::balanceOf(sender(), id1) == u256_from_u128(30), 118); + assert!(ERC1155::balanceOf(sender(), id2) == u256_from_u128(500), 119); + assert!(ERC1155::balanceOf(Alice, id1) == u256_from_u128(20), 120); + assert!(ERC1155::balanceOf(Alice, id2) == u256_from_u128(300), 121); + assert!(ERC1155::balanceOf(Bob, id1) == u256_from_u128(50), 122); + assert!(ERC1155::balanceOf(Bob, id2) == u256_from_u128(200), 123); + + assert!(ERC1155::balanceOf(sender(), id1) == u256_from_u128(100), 124); // expected to fail. + } +} diff --git a/vendors/move/crates/evm/examples/tests/ERC20Tests.move b/vendors/move/crates/evm/examples/tests/ERC20Tests.move new file mode 100644 index 000000000..1dccf4c03 --- /dev/null +++ b/vendors/move/crates/evm/examples/tests/ERC20Tests.move @@ -0,0 +1,37 @@ +module Evm::ERC20Tests { + use Evm::Evm::sender; + use Evm::U256::{zero, one, u256_from_u128}; + use std::vector; + use Evm::ERC20; + use std::ascii::{string}; + + const Alice: address = @0x8877; + const Bob: address = @0x8888; + + #[test] + fun test_create() { + ERC20::create(string(vector::empty()), string(vector::empty()), one()); + assert!(ERC20::balanceOf(sender()) == one(), 100); + assert!(ERC20::balanceOf(Alice) == zero(), 101); + assert!(ERC20::balanceOf(Bob) == zero(), 102); + } + + #[test] + fun test_balance_of() { + ERC20::create(string(vector::empty()), string(vector::empty()), one()); + assert!(ERC20::balanceOf(sender()) == one(), 103); + assert!(ERC20::balanceOf(Alice) == zero(), 104); + assert!(ERC20::balanceOf(Bob) == zero(), 105); + } + + #[test] + #[expected_failure(abort_code = 109)] + fun test_transfer() { + ERC20::create(string(vector::empty()), string(vector::empty()), u256_from_u128(7)); + ERC20::transfer(Alice, one()); + assert!(ERC20::balanceOf(sender()) == u256_from_u128(6), 106); + assert!(ERC20::balanceOf(Alice) == one(), 107); + assert!(ERC20::balanceOf(Bob) == zero(), 108); + assert!(ERC20::balanceOf(sender()) == u256_from_u128(7), 109); // expected to fail + } +} diff --git a/vendors/move/crates/evm/exec-utils/Cargo.toml b/vendors/move/crates/evm/exec-utils/Cargo.toml new file mode 100644 index 000000000..d5786f5d5 --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "evm-exec-utils" +version = "0.1.0" +authors = ["Diem Association "] +edition = "2021" +license = "Apache-2.0" +publish = false +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.52" +evm = { version = "0.33.1", features = [ "tracing"] } +evm-runtime = { version = "0.33.0", features = [ "tracing"] } +hex = "0.4.3" +primitive-types = "0.10.1" +# external dependencies +sha3 = "0.9.1" +tempfile = "3.2.0" + +# move dependencies +move-command-line-common = { path = "../../move-command-line-common" } diff --git a/vendors/move/crates/evm/exec-utils/contracts/a_plus_b.sol b/vendors/move/crates/evm/exec-utils/contracts/a_plus_b.sol new file mode 100644 index 000000000..6a69dd2bd --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/contracts/a_plus_b.sol @@ -0,0 +1,11 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.10; + +contract APlusB { + function plus(uint a, uint b) public pure returns(uint) { + return a + b; + } +} diff --git a/vendors/move/crates/evm/exec-utils/contracts/hello_world.sol b/vendors/move/crates/evm/exec-utils/contracts/hello_world.sol new file mode 100644 index 000000000..c1ad630c3 --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/contracts/hello_world.sol @@ -0,0 +1,9 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.10; + +contract HelloWorld { + string public greet = "Hello World!"; +} diff --git a/vendors/move/crates/evm/exec-utils/contracts/stateful.sol b/vendors/move/crates/evm/exec-utils/contracts/stateful.sol new file mode 100644 index 000000000..d2cabea34 --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/contracts/stateful.sol @@ -0,0 +1,17 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.10; + +contract TwoFunctions { + uint counter = 0x0; + + function inc() public { + counter = counter + 1; + } + + function get() public view returns(uint) { + return counter; + } +} diff --git a/vendors/move/crates/evm/exec-utils/contracts/two_functions.sol b/vendors/move/crates/evm/exec-utils/contracts/two_functions.sol new file mode 100644 index 000000000..0fd905ad0 --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/contracts/two_functions.sol @@ -0,0 +1,13 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.10; + +contract TwoFunctions { + function panic() pure public { + assert(false); + } + + function do_nothing() public {} +} diff --git a/vendors/move/crates/evm/exec-utils/src/compile.rs b/vendors/move/crates/evm/exec-utils/src/compile.rs new file mode 100644 index 000000000..beb658eae --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/src/compile.rs @@ -0,0 +1,129 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::{anyhow, bail, format_err, Result}; +use std::{ + collections::BTreeMap, + ffi::OsStr, + fs::{self}, + io::Write, + path::{Path, PathBuf}, + process::{Command, Stdio}, +}; + +// Unfortunately, solc can run the Yul compiler only to stdout, not supporting the -o option. +// It uses some markers in stdout which we match on to find the relevant parts. This is fragile +// and may need to be fixed if solc starts changing its output. +const OPTIMIZED_YUL_MARKER: &str = "\nPretty printed source:"; +const HEX_OUTPUT_MARKER: &str = "\nBinary representation:"; + +fn solc_path() -> Result { + let solc_exe = move_command_line_common::env::read_env_var("SOLC_EXE"); + + if solc_exe.is_empty() { + bail!( + "failed to resolve path to solc (Solidity compiler). + Is the environment variable SOLC_EXE set? + Did you run `./scripts/dev_setup.sh -d`?" + ) + } + + Ok(PathBuf::from(&solc_exe)) +} + +fn solc_impl( + source_paths: impl IntoIterator>, + output_dir: &Path, +) -> Result>> { + Command::new(solc_path()?) + .args(source_paths) + .arg("--bin") + .arg("-o") + .arg(output_dir) + .output() + .map_err(|err| format_err!("failed to call solc (solidity compiler): {:?}", err))?; + + let mut compiled_contracts = BTreeMap::new(); + + for entry in fs::read_dir(output_dir)? { + let entry = entry?; + + if entry.file_type()?.is_file() { + let path = entry.path(); + if let Some(ext) = path.extension() { + if ext == "bin" { + let data = fs::read(&path)?; + let data = hex::decode(data)?; + + compiled_contracts.insert( + path.file_stem() + .ok_or_else(|| format_err!("failed to extract file name"))? + .to_string_lossy() + .to_string(), + data, + ); + } + } + } + } + + Ok(compiled_contracts) +} + +/// Compile the solidity sources using solc. +/// Return a mapping with keys being contract names and values being compiled bytecode. +/// +/// The environment variable SOLC_EXE must point to solc. +pub fn solc( + source_paths: impl IntoIterator>, +) -> Result>> { + let temp = tempfile::tempdir()?; + + solc_impl(source_paths, temp.path()) +} + +/// Compile the Yul source, given as a string, and return the binary representation of the +/// compiled bytecode. If `return_optimized_yul` is true, also return the textual representation +/// of optimized Yul. +pub fn solc_yul(source: &str, return_optimized_yul: bool) -> Result<(Vec, Option)> { + let mut prog = Command::new(solc_path()?); + prog.arg("--optimize").arg("--strict-assembly").arg("--bin"); + if return_optimized_yul { + prog.arg("--ir-optimized"); + } + let mut child = prog + .arg("-") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn()?; + let pipe = child + .stdin + .as_mut() + .ok_or_else(|| anyhow!("cannot create pipe"))?; + pipe.write_all(source.as_bytes())?; + let out = child.wait_with_output()?; + if !out.status.success() { + return Err(anyhow!(String::from_utf8_lossy(&out.stderr).to_string())); + } + let out_str = String::from_utf8_lossy(&out.stdout).to_string(); + let start_of_yul = out_str.find(OPTIMIZED_YUL_MARKER); + let start_of_hex = out_str.find(HEX_OUTPUT_MARKER); + if return_optimized_yul && start_of_yul.is_none() || start_of_hex.is_none() { + return Err(anyhow!( + "Internal error: unexpected output of solc during Yul compilation" + )); + } + let yul = if return_optimized_yul { + Some( + out_str[(start_of_yul.unwrap() + OPTIMIZED_YUL_MARKER.len())..start_of_hex.unwrap()] + .trim() + .to_string(), + ) + } else { + None + }; + let bin = hex::decode(out_str[(start_of_hex.unwrap() + HEX_OUTPUT_MARKER.len())..].trim())?; + Ok((bin, yul)) +} diff --git a/vendors/move/crates/evm/exec-utils/src/exec.rs b/vendors/move/crates/evm/exec-utils/src/exec.rs new file mode 100644 index 000000000..3dfc6222f --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/src/exec.rs @@ -0,0 +1,248 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use evm::{ + backend::{Apply, ApplyBackend, Basic, MemoryAccount, MemoryBackend, MemoryVicinity}, + executor::stack::{MemoryStackState, StackExecutor, StackSubstateMetadata}, + Config, Context, CreateScheme, ExitReason, Runtime, +}; +use primitive_types::{H160, U256}; +use sha3::{Digest, Keccak256}; +use std::{collections::BTreeMap, error::Error, fmt, rc::Rc}; + +// TODO: implement these features: +// - Proper handling of gas + +/// Stateful EVM executor backed by an in-memory storage. +pub struct Executor<'v> { + storage_backend: MemoryBackend<'v>, +} + +/// Return the 4-byte method selector derived from the signature, which is encoded as a string (e.g. `"foo(uint256,uint256)"`). +// +// TODO: Rust type to represent the signature. +pub fn derive_method_selector(sig: &str) -> [u8; 4] { + let mut keccak = Keccak256::new(); + keccak.update(sig.as_bytes()); + let digest = keccak.finalize(); + [digest[0], digest[1], digest[2], digest[3]] +} + +#[derive(Debug)] +pub enum MintError { + BalanceOverflow, +} + +impl fmt::Display for MintError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +pub struct ExecuteResult { + pub exit_reason: ExitReason, + pub return_value: Vec, + pub used_gas: u64, +} + +impl fmt::Display for ExecuteResult { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{:?} (used_gas={}): {:?}", + self.exit_reason, self.used_gas, self.return_value + ) + } +} + +impl Error for MintError {} + +impl<'v> Executor<'v> { + /// Return a reference to the in-memory storage backend. + pub fn storage(&self) -> &MemoryBackend<'v> { + &self.storage_backend + } + + /// Return a reference to the in-memory representation of the account at the specified adress if one exists. + fn account_info(&self, address: H160) -> Option<&MemoryAccount> { + self.storage_backend.state().get(&address) + } + + /// Return the balance of the account at the specified address if one exists. + pub fn account_balance(&self, address: H160) -> Option { + self.account_info(address).map(|account| account.balance) + } + + /// Add balance to the specified account. + /// Intended to used for testing. + /// + /// Note: this will create a new account at the given address if one does not exist. + pub fn mint(&mut self, address: H160, eth_amount: U256) -> Result<(), MintError> { + let (balance, nonce) = match self.account_info(address) { + Some(account) => { + let balance = account + .balance + .checked_add(eth_amount) + .ok_or(MintError::BalanceOverflow)?; + let nonce = account.nonce; // REVIEW: should the nonce be incremented? + + (balance, nonce) + }, + None => (eth_amount, U256::from(0)), + }; + + self.storage_backend.apply( + [Apply::Modify { + address, + basic: Basic { balance, nonce }, + code: None, + storage: [], + reset_storage: false, + }], + [], + false, + ); + + Ok(()) + } + + /// Create a new `Executor` with an empty in-memory storage backend. + // + // TODO: review the lifetime of vicinity. + pub fn new(vicinity: &'v MemoryVicinity) -> Self { + Self { + storage_backend: MemoryBackend::new(vicinity, BTreeMap::new()), + } + } + + // Perform a transaction and commit the changes to the storage backend. + fn transact(&mut self, op: F) -> R + where + F: for<'c> FnOnce( + &mut StackExecutor<'c, 'static, MemoryStackState<'c, 'c, MemoryBackend<'v>>, ()>, + ) -> R, + { + let config = Config::london(); + let metadata = StackSubstateMetadata::new(u64::MAX, &config); + let state = MemoryStackState::new(metadata, &self.storage_backend); + let mut exec = StackExecutor::new_with_precompiles(state, &config, &()); + + let res = op(&mut exec); + + let state = exec.into_state(); + let (changes, logs) = state.deconstruct(); + self.storage_backend.apply(changes, logs, false); + + res + } + + /// Create a contract and return the contract address if successful. + pub fn create_contract( + &mut self, + caller_address: H160, + contract_code: Vec, + ) -> Result { + self.transact(|exec| { + let contract_address = exec.create_address(CreateScheme::Legacy { + caller: caller_address, + }); + + let exit_reason = exec.transact_create( + caller_address, + U256::zero(), // TODO: allow the caller to specify this. + contract_code, + u64::MAX, + vec![], + ); + + match &exit_reason { + ExitReason::Succeed(_) => Ok(contract_address), + _ => Err(exit_reason), + } + }) + } + + /// Transfer some ETH from one account to another. + pub fn transfer_eth( + &mut self, + sender_address: H160, + receipient_address: H160, + eth_amount: U256, + ) -> Result<(), ExitReason> { + self.transact(|exec| { + let (exit_reason, _buffer) = exec.transact_call( + sender_address, + receipient_address, + eth_amount, + vec![], + u64::MAX, + vec![], + ); + + match &exit_reason { + ExitReason::Succeed(_) => Ok(()), + _ => Err(exit_reason), + } + }) + } + + /// Call a contract method with the given signature. + /// The signature is represented by a string consisting of the name of the method and + /// a list of parameter types (e.g. `foo(uint256,uint256)`). + pub fn call_function( + &mut self, + caller_address: H160, + contract_address: H160, + eth_amount: U256, + method_sig: &str, + method_args: &[u8], + ) -> (ExitReason, Vec) { + self.transact(|exec| { + let mut data = vec![]; + data.extend(derive_method_selector(method_sig)); + data.extend(method_args); + + let (exit_reason, buffer) = exec.transact_call( + caller_address, + contract_address, + eth_amount, + data, + u64::MAX, + vec![], + ); + + (exit_reason, buffer) + }) + } + + /// Execute custom EVM opecodes. + /// You are still required to specify a caller address and a contract address, even though a contract may not exist + /// at the specified address. + pub fn execute_custom_code( + &mut self, + caller_address: H160, + contract_address: H160, + code: Vec, + data: Vec, + ) -> ExecuteResult { + self.transact(|exec| { + let context = Context { + address: contract_address, + caller: caller_address, + apparent_value: U256::zero(), // TODO: figure out what this is. + }; + let mut runtime = Runtime::new(Rc::new(code), Rc::new(data), context, exec.config()); + + // REVIEW: are we handling gas metering correctly? + let exit_reason = exec.execute(&mut runtime); + let return_value = runtime.machine().return_value(); + let used_gas = exec.used_gas(); + ExecuteResult { + exit_reason, + return_value, + used_gas, + } + }) + } +} diff --git a/vendors/move/crates/evm/exec-utils/src/lib.rs b/vendors/move/crates/evm/exec-utils/src/lib.rs new file mode 100644 index 000000000..794141275 --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/src/lib.rs @@ -0,0 +1,9 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pub mod compile; +pub mod exec; +#[cfg(test)] +pub mod tests; +pub mod tracing; diff --git a/vendors/move/crates/evm/exec-utils/src/tests.rs b/vendors/move/crates/evm/exec-utils/src/tests.rs new file mode 100644 index 000000000..fb93aacc3 --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/src/tests.rs @@ -0,0 +1,201 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::{compile::solc, exec::Executor}; +use anyhow::Result; +use evm::{backend::MemoryVicinity, ExitReason, Opcode}; +use primitive_types::{H160, U256}; +use std::path::{Path, PathBuf}; + +fn contract_path(file_name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("contracts") + .join(file_name) +} + +fn test_vincinity() -> MemoryVicinity { + MemoryVicinity { + gas_price: 0.into(), + origin: H160::zero(), + chain_id: 0.into(), + block_hashes: vec![], + block_number: 0.into(), + block_coinbase: H160::zero(), + block_timestamp: 0.into(), + block_difficulty: 0.into(), + block_gas_limit: U256::MAX, + block_base_fee_per_gas: 0.into(), + } +} + +#[test] +fn test_hello_world() -> Result<()> { + let (_contract_name, contract_code) = solc([contract_path("hello_world.sol")])? + .into_iter() + .next() + .unwrap(); + + let vicinity = test_vincinity(); + let mut exec = Executor::new(&vicinity); + + let res = exec.create_contract(H160::zero(), contract_code); + assert!(res.is_ok()); + + Ok(()) +} + +#[test] +fn test_two_functions() -> Result<()> { + let (_contract_name, contract_code) = solc([contract_path("two_functions.sol")])? + .into_iter() + .next() + .unwrap(); + + let vicinity = test_vincinity(); + let mut exec = Executor::new(&vicinity); + + let contract_address = exec + .create_contract(H160::zero(), contract_code) + .expect("failed to create contract"); + + let (exit_reason, _buffer) = + exec.call_function(H160::zero(), contract_address, 0.into(), "do_nothing()", &[ + ]); + assert!(matches!(exit_reason, ExitReason::Succeed(_))); + + let (exit_reason, _buffer) = + exec.call_function(H160::zero(), contract_address, 0.into(), "panic()", &[]); + assert!(matches!(exit_reason, ExitReason::Revert(_))); + + Ok(()) +} + +#[test] +fn test_a_plus_b() -> Result<()> { + let (_contract_name, contract_code) = solc([contract_path("a_plus_b.sol")])? + .into_iter() + .next() + .unwrap(); + + let vicinity = test_vincinity(); + let mut exec = Executor::new(&vicinity); + + let contract_address = exec + .create_contract(H160::zero(), contract_code) + .expect("failed to create contract"); + + let mut args = [0u8; 64]; + args[0] = 1; + args[32] = 2; + + let (exit_reason, buffer) = exec.call_function( + H160::zero(), + contract_address, + 0.into(), + "plus(uint256,uint256)", + &args, + ); + assert!(matches!(exit_reason, ExitReason::Succeed(_))); + + assert!(buffer.len() >= 32); + let mut expected = [0u8; 32]; + expected[0] = 0x3; + assert_eq!(&buffer[..32], &expected); + + Ok(()) +} + +#[test] +fn test_stateful() -> Result<()> { + let (_contract_name, contract_code) = solc([contract_path("stateful.sol")])? + .into_iter() + .next() + .unwrap(); + + let vicinity = test_vincinity(); + let mut exec = Executor::new(&vicinity); + + let contract_address = exec + .create_contract(H160::zero(), contract_code) + .expect("failed to create contract"); + + for _ in 0..7 { + let (exit_reason, _buffer) = + exec.call_function(H160::zero(), contract_address, 0.into(), "inc()", &[]); + assert!(matches!(exit_reason, ExitReason::Succeed(_))); + } + + let (exit_reason, buffer) = + exec.call_function(H160::zero(), contract_address, 0.into(), "get()", &[]); + assert!(matches!(exit_reason, ExitReason::Succeed(_))); + + assert!(buffer.len() >= 32); + let mut expected = [0u8; 32]; + expected[31] = 0x7; + assert_eq!(&buffer[..32], &expected); + + Ok(()) +} + +#[test] +fn test_custom_code_add_two_numbers() -> Result<()> { + let vicinity = test_vincinity(); + let mut exec = Executor::new(&vicinity); + + let mut code = vec![]; + + // push 1 + // push 2 + // add + // push 0 + // mstore + // push 32 + // push 0 + // return + + code.extend([Opcode::PUSH1.0, 0x1, Opcode::PUSH1.0, 0x2, Opcode::ADD.0]); + + code.push(Opcode::PUSH32.0); + code.extend([0; 32]); + code.push(Opcode::MSTORE.0); + + let mut length = [0; 32]; + length[31] = 32; + code.push(Opcode::PUSH32.0); + code.extend(length); + code.push(Opcode::PUSH32.0); + code.extend([0; 32]); + code.push(Opcode::RETURN.0); + + let ret = exec.execute_custom_code(H160::zero(), H160::zero(), code, vec![]); + + let mut expected = [0; 32]; + expected[31] = 0x3; + assert_eq!(&ret.return_value, &expected); + + Ok(()) +} + +#[test] +fn test_transfer_eth() -> Result<()> { + let vicinity = test_vincinity(); + let mut exec = Executor::new(&vicinity); + + let alice_addr = H160::from([0x1; 20]); + let bob_addr = H160::from([0x2; 20]); + + exec.mint(alice_addr, U256::from(5000))?; + exec.mint(bob_addr, U256::from(5000))?; + + assert_eq!(exec.account_balance(alice_addr).unwrap(), U256::from(5000)); + assert_eq!(exec.account_balance(bob_addr).unwrap(), U256::from(5000)); + + exec.transfer_eth(alice_addr, bob_addr, U256::from(1000)) + .expect("failed to transfer eth"); + + assert_eq!(exec.account_balance(alice_addr).unwrap(), U256::from(4000)); + assert_eq!(exec.account_balance(bob_addr).unwrap(), U256::from(6000)); + + Ok(()) +} diff --git a/vendors/move/crates/evm/exec-utils/src/tracing.rs b/vendors/move/crates/evm/exec-utils/src/tracing.rs new file mode 100644 index 000000000..70ed22e42 --- /dev/null +++ b/vendors/move/crates/evm/exec-utils/src/tracing.rs @@ -0,0 +1,288 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use evm::Opcode; +use evm_runtime::tracing::{ + using as runtime_using, Event as RuntimeEvent, EventListener as RuntimeEventListener, +}; + +/// Enables tracing of the EVN runtime during the execution of `f`. +pub fn trace_runtime(f: F) -> R +where + F: FnOnce() -> R, +{ + let mut listener = RuntimeListener(); + runtime_using(&mut listener, f) +} + +struct RuntimeListener(); + +impl RuntimeEventListener for RuntimeListener { + fn event(&mut self, event: RuntimeEvent) { + use RuntimeEvent::*; + match event { + Step { opcode, stack, .. } => { + println!("{}", opc_name(opcode)); + println!(" stack:"); + for i in (0..stack.len()).rev() { + println!(" {}", stack.data()[i]) + } + }, + StepResult { + result, + return_value, + .. + } => { + println!("==> {:?} (ret={:?})", result, return_value) + }, + SLoad { index, value, .. } => { + println!("==> storage {} -> {}", index, value) + }, + SStore { index, value, .. } => { + println!("==> storage {} <- {}", index, value) + }, + } + } +} + +/// Returns the name of an opcode. +/// +/// Implementation remark: this should be in the evm-runtime crate, but did not find it. +/// We generated this by regular expression replacement of the definition in `evm_core::opcode`. +fn opc_name(code: Opcode) -> String { + match code { + // `STOP` + Opcode::STOP => "STOP".to_string(), + // `ADD` + Opcode::ADD => "ADD".to_string(), + // `MUL` + Opcode::MUL => "MUL".to_string(), + // `SUB` + Opcode::SUB => "SUB".to_string(), + // `DIV` + Opcode::DIV => "DIV".to_string(), + // `SDIV` + Opcode::SDIV => "SDIV".to_string(), + // `MOD` + Opcode::MOD => "MOD".to_string(), + // `SMOD` + Opcode::SMOD => "SMOD".to_string(), + // `ADDMOD` + Opcode::ADDMOD => "ADDMOD".to_string(), + // `MULMOD` + Opcode::MULMOD => "MULMOD".to_string(), + // `EXP` + Opcode::EXP => "EXP".to_string(), + // `SIGNEXTEND` + Opcode::SIGNEXTEND => "SIGNEXTEND".to_string(), + + // `LT` + Opcode::LT => "LT".to_string(), + // `GT` + Opcode::GT => "GT".to_string(), + // `SLT` + Opcode::SLT => "SLT".to_string(), + // `SGT` + Opcode::SGT => "SGT".to_string(), + // `EQ` + Opcode::EQ => "EQ".to_string(), + // `ISZERO` + Opcode::ISZERO => "ISZERO".to_string(), + // `AND` + Opcode::AND => "AND".to_string(), + // `OR` + Opcode::OR => "OR".to_string(), + // `XOR` + Opcode::XOR => "XOR".to_string(), + // `NOT` + Opcode::NOT => "NOT".to_string(), + // `BYTE` + Opcode::BYTE => "BYTE".to_string(), + + // `CALLDATALOAD` + Opcode::CALLDATALOAD => "CALLDATALOAD".to_string(), + // `CALLDATASIZE` + Opcode::CALLDATASIZE => "CALLDATASIZE".to_string(), + // `CALLDATACOPY` + Opcode::CALLDATACOPY => "CALLDATACOPY".to_string(), + // `CODESIZE` + Opcode::CODESIZE => "CODESIZE".to_string(), + // `CODECOPY` + Opcode::CODECOPY => "CODECOPY".to_string(), + + // `SHL` + Opcode::SHL => "SHL".to_string(), + // `SHR` + Opcode::SHR => "SHR".to_string(), + // `SAR` + Opcode::SAR => "SAR".to_string(), + + // `POP` + Opcode::POP => "POP".to_string(), + // `MLOAD` + Opcode::MLOAD => "MLOAD".to_string(), + // `MSTORE` + Opcode::MSTORE => "MSTORE".to_string(), + // `MSTORE8` + Opcode::MSTORE8 => "MSTORE8".to_string(), + // `JUMP` + Opcode::JUMP => "JUMP".to_string(), + // `JUMPI` + Opcode::JUMPI => "JUMPI".to_string(), + // `PC` + Opcode::PC => "PC".to_string(), + // `MSIZE` + Opcode::MSIZE => "MSIZE".to_string(), + // `JUMPDEST` + Opcode::JUMPDEST => "JUMPDEST".to_string(), + + // `PUSHn` + Opcode::PUSH1 => "PUSH1".to_string(), + Opcode::PUSH2 => "PUSH2".to_string(), + Opcode::PUSH3 => "PUSH3".to_string(), + Opcode::PUSH4 => "PUSH4".to_string(), + Opcode::PUSH5 => "PUSH5".to_string(), + Opcode::PUSH6 => "PUSH6".to_string(), + Opcode::PUSH7 => "PUSH7".to_string(), + Opcode::PUSH8 => "PUSH8".to_string(), + Opcode::PUSH9 => "PUSH9".to_string(), + Opcode::PUSH10 => "PUSH10".to_string(), + Opcode::PUSH11 => "PUSH11".to_string(), + Opcode::PUSH12 => "PUSH12".to_string(), + Opcode::PUSH13 => "PUSH13".to_string(), + Opcode::PUSH14 => "PUSH14".to_string(), + Opcode::PUSH15 => "PUSH15".to_string(), + Opcode::PUSH16 => "PUSH16".to_string(), + Opcode::PUSH17 => "PUSH17".to_string(), + Opcode::PUSH18 => "PUSH18".to_string(), + Opcode::PUSH19 => "PUSH19".to_string(), + Opcode::PUSH20 => "PUSH20".to_string(), + Opcode::PUSH21 => "PUSH21".to_string(), + Opcode::PUSH22 => "PUSH22".to_string(), + Opcode::PUSH23 => "PUSH23".to_string(), + Opcode::PUSH24 => "PUSH24".to_string(), + Opcode::PUSH25 => "PUSH25".to_string(), + Opcode::PUSH26 => "PUSH26".to_string(), + Opcode::PUSH27 => "PUSH27".to_string(), + Opcode::PUSH28 => "PUSH28".to_string(), + Opcode::PUSH29 => "PUSH29".to_string(), + Opcode::PUSH30 => "PUSH30".to_string(), + Opcode::PUSH31 => "PUSH31".to_string(), + Opcode::PUSH32 => "PUSH32".to_string(), + + // `DUPn` + Opcode::DUP1 => "DUP1".to_string(), + Opcode::DUP2 => "DUP2".to_string(), + Opcode::DUP3 => "DUP3".to_string(), + Opcode::DUP4 => "DUP4".to_string(), + Opcode::DUP5 => "DUP5".to_string(), + Opcode::DUP6 => "DUP6".to_string(), + Opcode::DUP7 => "DUP7".to_string(), + Opcode::DUP8 => "DUP8".to_string(), + Opcode::DUP9 => "DUP9".to_string(), + Opcode::DUP10 => "DUP10".to_string(), + Opcode::DUP11 => "DUP11".to_string(), + Opcode::DUP12 => "DUP12".to_string(), + Opcode::DUP13 => "DUP13".to_string(), + Opcode::DUP14 => "DUP14".to_string(), + Opcode::DUP15 => "DUP15".to_string(), + Opcode::DUP16 => "DUP16".to_string(), + + // `SWAPn` + Opcode::SWAP1 => "SWAP1".to_string(), + Opcode::SWAP2 => "SWAP2".to_string(), + Opcode::SWAP3 => "SWAP3".to_string(), + Opcode::SWAP4 => "SWAP4".to_string(), + Opcode::SWAP5 => "SWAP5".to_string(), + Opcode::SWAP6 => "SWAP6".to_string(), + Opcode::SWAP7 => "SWAP7".to_string(), + Opcode::SWAP8 => "SWAP8".to_string(), + Opcode::SWAP9 => "SWAP9".to_string(), + Opcode::SWAP10 => "SWAP10".to_string(), + Opcode::SWAP11 => "SWAP11".to_string(), + Opcode::SWAP12 => "SWAP12".to_string(), + Opcode::SWAP13 => "SWAP13".to_string(), + Opcode::SWAP14 => "SWAP14".to_string(), + Opcode::SWAP15 => "SWAP15".to_string(), + Opcode::SWAP16 => "SWAP16".to_string(), + + // `RETURN` + Opcode::RETURN => "RETURN".to_string(), + // `REVERT` + Opcode::REVERT => "REVERT".to_string(), + + // `INVALID` + Opcode::INVALID => "INVALID".to_string(), + + // `SHA3` + Opcode::SHA3 => "SHA3".to_string(), + // `ADDRESS` + Opcode::ADDRESS => "ADDRESS".to_string(), + // `BALANCE` + Opcode::BALANCE => "BALANCE".to_string(), + // `SELFBALANCE` + Opcode::SELFBALANCE => "SELFBALANCE".to_string(), + // `BASEFEE` + Opcode::BASEFEE => "BASEFEE".to_string(), + // `ORIGIN` + Opcode::ORIGIN => "ORIGIN".to_string(), + // `CALLER` + Opcode::CALLER => "CALLER".to_string(), + // `CALLVALUE` + Opcode::CALLVALUE => "CALLVALUE".to_string(), + // `GASPRICE` + Opcode::GASPRICE => "GASPRICE".to_string(), + // `EXTCODESIZE` + Opcode::EXTCODESIZE => "EXTCODESIZE".to_string(), + // `EXTCODECOPY` + Opcode::EXTCODECOPY => "EXTCODECOPY".to_string(), + // `EXTCODEHASH` + Opcode::EXTCODEHASH => "EXTCODEHASH".to_string(), + // `RETURNDATASIZE` + Opcode::RETURNDATASIZE => "RETURNDATASIZE".to_string(), + // `RETURNDATACOPY` + Opcode::RETURNDATACOPY => "RETURNDATACOPY".to_string(), + // `BLOCKHASH` + Opcode::BLOCKHASH => "BLOCKHASH".to_string(), + // `COINBASE` + Opcode::COINBASE => "COINBASE".to_string(), + // `TIMESTAMP` + Opcode::TIMESTAMP => "TIMESTAMP".to_string(), + // `NUMBER` + Opcode::NUMBER => "NUMBER".to_string(), + // `DIFFICULTY` + Opcode::DIFFICULTY => "DIFFICULTY".to_string(), + // `GASLIMIT` + Opcode::GASLIMIT => "GASLIMIT".to_string(), + // `SLOAD` + Opcode::SLOAD => "SLOAD".to_string(), + // `SSTORE` + Opcode::SSTORE => "SSTORE".to_string(), + // `GAS` + Opcode::GAS => "GAS".to_string(), + // `LOGn` + Opcode::LOG0 => "LOG0".to_string(), + Opcode::LOG1 => "LOG1".to_string(), + Opcode::LOG2 => "LOG2".to_string(), + Opcode::LOG3 => "LOG3".to_string(), + Opcode::LOG4 => "LOG4".to_string(), + // `CREATE` + Opcode::CREATE => "CREATE".to_string(), + // `CREATE2` + Opcode::CREATE2 => "CREATE2".to_string(), + // `CALL` + Opcode::CALL => "CALL".to_string(), + // `CALLCODE` + Opcode::CALLCODE => "CALLCODE".to_string(), + // `DELEGATECALL` + Opcode::DELEGATECALL => "DELEGATECALL".to_string(), + // `STATICCALL` + Opcode::STATICCALL => "STATICCALL".to_string(), + // `SUICIDE` + Opcode::SUICIDE => "SUICIDE".to_string(), + // `CHAINID` + Opcode::CHAINID => "CHAINID".to_string(), + _ => format!("opc #{:x}", code.as_usize()), + } +} diff --git a/vendors/move/crates/evm/extract-ethereum-abi/Cargo.toml b/vendors/move/crates/evm/extract-ethereum-abi/Cargo.toml new file mode 100644 index 000000000..43dd6c784 --- /dev/null +++ b/vendors/move/crates/evm/extract-ethereum-abi/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "extract-ethereum-abi" +version = "0.1.0" +authors = ["Diem Association "] +description = "Extract Etherem ABI" +publish = false +edition = "2021" +license = "Apache-2.0" + +[dependencies] +move-core-types = { path = "../../move-core-types" } +# move dependencies +move-ethereum-abi = { path = "../move-ethereum-abi" } +move-to-yul = { path = "../move-to-yul" } + +# external dependencies +anyhow = "1.0.38" +atty = "0.2.14" +clap = { version = "3", features = ["derive", "env"] } +codespan = "0.11.1" +codespan-reporting = "0.11.1" +ethabi = "17.0.0" +once_cell = "1.7.2" +regex = "1.4.3" +serde = { version = "1.0.124", features = ["derive"] } +serde_json = "1.0.64" diff --git a/vendors/move/crates/evm/extract-ethereum-abi/src/main.rs b/vendors/move/crates/evm/extract-ethereum-abi/src/main.rs new file mode 100644 index 000000000..c0dba283c --- /dev/null +++ b/vendors/move/crates/evm/extract-ethereum-abi/src/main.rs @@ -0,0 +1,39 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +use clap::Parser; +use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; +use move_to_yul::{options::Options, parse_metadata_to_move_sig, run_to_abi_metadata}; + +fn main() { + if let Err(e) = run() { + eprintln!("{}", e); + let mut c = e.source(); + while let Some(s) = c { + eprintln!("caused by: {}", s); + c = s.source(); + } + std::process::exit(1) + } +} + +fn run() -> anyhow::Result<()> { + let options = Options::parse(); + let color = if atty::is(atty::Stream::Stderr) && atty::is(atty::Stream::Stdout) { + ColorChoice::Auto + } else { + ColorChoice::Never + }; + let mut error_writer = StandardStream::stderr(color); + let metadata_vec = run_to_abi_metadata(&mut error_writer, options).unwrap(); + for metadata in metadata_vec { + let move_sig_opt = parse_metadata_to_move_sig(&metadata); + if let Some(move_sig) = move_sig_opt { + println!("{}", serde_json::to_string_pretty(&move_sig).unwrap()); + } + } + Ok(()) +} diff --git a/vendors/move/crates/evm/hardhat-examples/.gitignore b/vendors/move/crates/evm/hardhat-examples/.gitignore new file mode 100644 index 000000000..36077f288 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/.gitignore @@ -0,0 +1,9 @@ +node_modules +.env +coverage +coverage.json +typechain + +#Hardhat files +cache +artifacts diff --git a/vendors/move/crates/evm/hardhat-examples/README.md b/vendors/move/crates/evm/hardhat-examples/README.md new file mode 100644 index 000000000..99cb758c2 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/README.md @@ -0,0 +1,21 @@ +# Hardhat Project for Move-on-EVM. + +This directory contains a Hardhat project for Move-on-EVM. The `contracts` directory contains Move contracts (e.g., `FortyTwo.move`) and the equivalent Solidity contracts (e.g., `FortyTwo.sol`). This directory contains the Move implementations for ERC20, ERC721 and ERC1155. The `test` directory contains test files (e.g., `FortyTwo.test.js`) to test both Move contracts and Solidity contracts. The `script` directory contains the script files to deploy the Move contracts on a network. + +To use this project, the hardhat environment (https://hardhat.org/tutorial/setting-up-the-environment.html) must to be set up first. Moreover, [`hardhat-move`](../hardhat-move/README.md) needs to be installed. + +To compile the contracts, use the following Hardhat command: +``` +$ npx hardhat compile +``` + +To test, use the following command: +``` +$ npx hardhat test +``` +At the end of the tests, a gas report will be generated. + +You can deploy the Move contracts a network once after you properly key values in `hardhat.config.js`. To deploy ERC721 on the rinkeby Ethereum testnet (for example), use the following command: +``` +$ npx hardhat run scripts/deploy_ERC721.js --network rinkeby +``` diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ABIStruct/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ABIStruct/Move.toml new file mode 100644 index 000000000..3dd2c9a05 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ABIStruct/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "ABIStruct" +version = "0.0.0" + +[addresses] +std = "0x1" +Evm = "0x2" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ABIStruct/sources/ABIStruct.move b/vendors/move/crates/evm/hardhat-examples/contracts/ABIStruct/sources/ABIStruct.move new file mode 100644 index 000000000..f33cbe459 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ABIStruct/sources/ABIStruct.move @@ -0,0 +1,77 @@ +#[evm_contract] +module Evm::ABIStruct { + use std::vector; + use std::ascii::{Self, String}; + use Evm::Evm::{emit}; + + + #[external(sig=b"safeTransferFrom(S) returns (S2)")] + public native fun safe_transfer_form(contract: address, s: S): S2; + + + #[abi_struct(sig=b"S(uint64, bool, S2)")] + struct S has drop, copy { + a: u64, + b: bool, + c: S2 + } + + #[abi_struct(sig=b"S2(uint64)")] + struct S2 has drop, copy { + x: u64 + } + + #[event(sig=b"Event_u64(uint64)")] + struct Event_u64 { + s: u64 + } + + #[event(sig=b"Event_String(String)")] + struct Event_String { + s: String + } + + #[callable(sig=b"test(S) returns (uint64)")] + fun test_2_S(s: S): u64 { + emit(Event_u64{s: s.a}); + s.a + } + + #[callable(sig=b"safe_transfer_form(address)")] + fun test_external_safe_transfer_from(addr: address) { + let s = pack_S(100, true); + let s2 = safe_transfer_form(addr, s); + emit(Event_u64{s: s2.x}); + } + + fun pack_S2(x: u64): S2 { + S2{x} + } + + fun pack_S(a: u64, b: bool): S { + let s2 = pack_S2(a); + S{a, b, c: s2} + } + + #[event(sig=b"Event_S(S)")] + struct Event_S { + s: S + } + + #[event(sig=b"Event_S2(S2)")] + struct Event_S2 { + s: S2 + } + + #[callable] + fun do_transfer(){ + let s = pack_S(42, true); + emit(Event_S{s}); + } + + #[callable(sig=b"test_string(String)")] + fun test_String_struct(s: String) { + emit(Event_String{s}); + } + +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/AsyncEvent/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/AsyncEvent/Move.toml new file mode 100644 index 000000000..e0c21d6f0 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/AsyncEvent/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "AsyncEvent" +version = "0.0.0" + +[addresses] +std = "0x1" +Evm = "0x2" +Async = "0x1" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } +MoveStdlib = { local = "../../../../move-stdlib" } +MoveAsyncLib = { local = "../../../../extensions/async/move-async-lib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/AsyncEvent/sources/AccountStateMachine.move b/vendors/move/crates/evm/hardhat-examples/contracts/AsyncEvent/sources/AccountStateMachine.move new file mode 100644 index 000000000..01fd6c13b --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/AsyncEvent/sources/AccountStateMachine.move @@ -0,0 +1,102 @@ +#[actor] +/// This is an instance of the Account example using an explicit state machine and one-way message passing. +/// +/// In this example, we need to manage rpc state explicitly, remembering any outstanding transfers in the +/// actors state. This creates a little more code, but also is somehow more transparent and true to the +/// transactional semantics of Move. This version implements an additional `cleanup` message which cancels +/// pending transactions over a certain age. +module 0x3::AccountStateMachine { + + use Async::Actor::{self, virtual_time}; + use std::vector; + + const MAX: u64 = 43; + const MAX_TRANSFER_AGE: u128 = 100000000; + + #[state] + struct Account { + value: u64, + xfer_id_counter: u64, + pending: vector + } + + struct PendingTransfer has drop { + xfer_id: u64, + amount: u64, + initiated_at: u128, + } + + #[init] + fun init(): Account { + Account{value: 0, xfer_id_counter: 0, pending: vector::empty()} + } + + #[message] + fun deposit(this: &mut Account, v: u64) { + assert!(MAX - this.value >= v, 1); + this.value = this.value + v; + } + + #[message] + fun withdraw(this: &mut Account, v: u64) { + assert!(this.value >= v, 2); + this.value = this.value - v; + } + + #[message] + fun xfer(this: &mut Account, dest: address, v: u64) { + // Do not initiate the transfer if there are not enough funds + // Remove this assert to test event + // assert!(this.value >= v, 1); + let xfer_id = new_xfer_id(this); + vector::push_back(&mut this.pending, PendingTransfer{xfer_id, amount: v, initiated_at: virtual_time()}); + // Call into a special version of deposit which calls us back once done. + send_xfer_deposit(dest, v, self(), xfer_id); + } + + fun new_xfer_id(this: &mut Account): u64 { + let counter = &mut this.xfer_id_counter; + let xfer_id = *counter; + *counter = *counter + 1; + xfer_id + } + + #[message] + fun xfer_deposit(this: &mut Account, v: u64, caller_: address, xfer_id: u64) { + deposit(this, v); + send_xfer_finish(caller_, xfer_id); + } + + #[message] + fun xfer_finish(this: &mut Account, xfer_id: u64) { + let i = find_xfer(this, xfer_id); + let amount = vector::borrow(&this.pending, i).amount; + vector::remove(&mut this.pending, i); + withdraw(this, amount) + } + + fun find_xfer(this: &Account, xfer_id: u64): u64 { + let pending = &this.pending; + let i = 0; + while (i < vector::length(pending) && vector::borrow(pending, i).xfer_id != xfer_id) { + i = i + 1; + }; + assert!(i < vector::length(pending), 3); + i + } + + #[message] + /// A periodical cleanup which removes dated pending transfers. + fun cleanup(this: &mut Account) { + let pending = &mut this.pending; + let i = 0; + while (i < vector::length(pending)) { + let p = vector::borrow(pending, i); + if (virtual_time() - p.initiated_at >= MAX_TRANSFER_AGE) { + vector::remove(pending, i); + } else { + i = i + 1; + } + } + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Callee.sol b/vendors/move/crates/evm/hardhat-examples/contracts/Callee.sol new file mode 100644 index 000000000..998c54f82 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Callee.sol @@ -0,0 +1,22 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +contract Callee { + +function success_uint() public pure returns (uint) { + return 42; +} + +function panic() public pure returns (uint) { + //assert(false); + uint i = 0; + uint j = 1; + return j/i; +} + +function ret_revert() public pure returns (uint) { + revert("revert"); + return 1; +} + +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Caller/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/Caller/Move.toml new file mode 100644 index 000000000..00a74aab9 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Caller/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "Caller" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Caller/sources/Caller.move b/vendors/move/crates/evm/hardhat-examples/contracts/Caller/sources/Caller.move new file mode 100644 index 000000000..aa31f25cc --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Caller/sources/Caller.move @@ -0,0 +1,50 @@ +#[evm_contract] +module Evm::Caller { + use Evm::U256::{Self, U256}; + use Evm::ExternalResult::{Self, ExternalResult}; + + #[external(sig=b"success_uint() returns (uint)")] + public native fun success(contract: address): ExternalResult; + + #[external(sig=b"panic() returns (uint)")] + public native fun panic(contract: address): ExternalResult; + + #[external(sig=b"ret_revert() returns (uint)")] + public native fun ret_revert(contract: address): ExternalResult; + + #[callable(sig=b"call_success(address) returns (uint)"), pure] + public fun call_success(addr: address): U256 { + let v = success(addr); + if (ExternalResult::is_ok(&v)) { + return ExternalResult::unwrap(v) + }; + return U256::zero() + } + + #[callable(sig=b"call_revert(address) returns (string)"), pure] + public fun call_revert(addr: address): vector { + let v = ret_revert(addr); + if (ExternalResult::is_ok(&v)) { + return b"success" + } else if (ExternalResult::is_err_reason(&v)) { + return ExternalResult::unwrap_err_reason(v) + } else if (ExternalResult::is_panic(&v)) { + return b"panic" + }; + return b"data" + } + + #[callable(sig=b"call_panic(address) returns (uint)"), pure] + public fun call_panic(addr: address): U256 { + let v = panic(addr); + if (ExternalResult::is_ok(&v)) { + return U256::zero(); + } else if (ExternalResult::is_err_reason(&v)) { + return U256::one(); + } else if (ExternalResult::is_panic(&v)) { + return ExternalResult::unwrap_panic(v) + }; + return U256::max() + } + +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock/Move.toml new file mode 100644 index 000000000..e0d87065e --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock/Move.toml @@ -0,0 +1,11 @@ +[package] +name = "ERC1155Mock" +version = "0.0.0" + +[addresses] +std = "0x1" +Evm = "0x2" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } +MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock/sources/ERC1155Mock.move b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock/sources/ERC1155Mock.move new file mode 100644 index 000000000..6fde3ba22 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock/sources/ERC1155Mock.move @@ -0,0 +1,389 @@ +#[evm_contract] +/// An implementation of the ERC-1155 Multi Token Standard. +module Evm::ERC1155Mock { + use Evm::Evm::{sender, self, sign, emit, isContract, abort_with, require}; + use Evm::Table::{Self, Table}; + use Evm::ExternalResult::{Self, ExternalResult}; + use Evm::U256::{Self, U256}; + use std::vector; + + // --------------------- + // For test only + // --------------------- + + #[callable(sig=b"setURI(string)")] + public fun setURI(newuri: vector) acquires State { + borrow_global_mut(self()).uri = newuri; + } + + #[callable(sig=b"mint(address,uint256,uint256,bytes)")] + public fun mint(to: address, id: U256, amount: U256, data: vector) acquires State { + mint_(to, id, amount, data); + } + + #[callable(sig=b"mintBatch(address,uint256[],uint256[],bytes)")] + public fun mintBatch(to: address, ids: vector, amounts: vector, data: vector) acquires State { + mintBatch_(to, ids, amounts, data); + } + + #[callable(sig=b"burn(address,uint256,uint256)")] + public fun burn(owner: address, id: U256, amount: U256) acquires State { + burn_(owner, id, amount); + } + + #[callable(sig=b"burnBatch(address,uint256[],uint256[])")] + public fun burnBatch(owner: address, ids: vector, amounts: vector) acquires State { + burnBatch_(owner, ids, amounts); + } + + + // --------------------- + // Evm::IERC1155Receiver + // --------------------- + + #[external(sig=b"onERC1155Received(address,address,uint256,uint256,bytes) returns (bytes4)")] + public native fun IERC1155Receiver_try_call_onERC1155Received(contract: address, operator: address, from: address, id: U256, amount: U256, bytes: vector): ExternalResult>; + + #[external(sig=b"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes) returns (bytes4)")] + public native fun IERC1155Receiver_try_call_onERC1155BatchReceived(contract: address, operator: address, from: address, ids: vector, amounts: vector, bytes: vector): ExternalResult>; + + /// Return the selector of the function `onERC1155Received` + public fun IERC1155Receiver_selector_onERC1155Received(): vector { + //bytes4(keccak256(b"onERC1155Received(address,address,uint256,uint256,bytes)")) + x"f23a6e61" + } + + /// Return the selector of the function `onERC1155Received` + public fun IERC1155Receiver_selector_onERC1155BatchReceived(): vector { + //bytes4(keccak256(b"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) + x"bc197c81" + } + + /// Return the interface identifier of this interface. + public fun IERC1155Receiver_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + // bytes_xor( + // IERC1155Receiver_selector_onERC1155Received(), + // IERC1155Receiver_selector_onERC1155BatchReceived() + // ) + //x"4e2312e0" + x"4e2312e1" // TODO: wrong value + } + + // --------------------- + // Evm::IERC165 + // --------------------- + public fun IERC165_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + //bytes4(keccak256(b"supportsInterface(bytes4)")) + x"01ffc9a7" + } + + // --------------------- + // Evm::IERC1155 + // --------------------- + public fun IERC1155_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + //bytes4(keccak256(b"supportsInterface(bytes4)")) + x"d9b67a26" + } + + #[event] + struct TransferSingle { + operator: address, + from: address, + to: address, + id: U256, + value: U256, + } + + #[event] + struct TransferBatch { + operator: address, + from: address, + to: address, + ids: vector, + values: vector, + } + + #[event] + struct ApprovalForAll { + account: address, + operator: address, + approved: bool, + } + + #[event] + struct URI { + value: vector, + id: U256, + } + + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + balances: Table>, + operatorApprovals: Table>, + uri: vector, + owner: address, // Implements the "ownable" pattern. + } + + #[create(sig=b"constructor(string)")] + /// Constructor of this contract. + public fun create(uri: vector) { + // Initial state of contract + move_to( + &sign(self()), + State { + balances: Table::empty>(), + operatorApprovals: Table::empty>(), + uri, + owner: sender(), + } + ); + } + + #[callable(sig=b"uri(uint256) returns (string)"), view] + /// Returns the name of the token + public fun uri(_id: U256): vector acquires State { + *&borrow_global(self()).uri + } + + #[callable(sig=b"balanceOf(address,uint256) returns (uint256)"), view] + /// Get the balance of an account's token. + public fun balanceOf(account: address, id: U256): U256 acquires State { + require(account != @0x0, b"ERC1155: balance query for the zero address"); + let s = borrow_global_mut(self()); + *mut_balanceOf(s, id, account) + } + + #[callable(sig=b"balanceOfBatch(address[],uint256[]) returns (uint256[])"), view] + /// Get the balance of multiple account/token pairs. + public fun balanceOfBatch(accounts: vector
, ids: vector): vector acquires State { + require(vector::length(&accounts) == vector::length(&ids), b"ERC1155: accounts and ids length mismatch"); + let len = vector::length(&accounts); + let i = 0; + let balances = vector::empty(); + while(i < len) { + vector::push_back( + &mut balances, + balanceOf( + *vector::borrow(&accounts, i), + *vector::borrow(&ids, i) + ) + ); + i = i + 1; + }; + balances + } + + #[callable(sig=b"setApprovalForAll(address,bool)")] + /// Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. + public fun setApprovalForAll(operator: address, approved: bool) acquires State { + let owner = sender(); + require(owner != operator, b"ERC1155: setting approval status for self"); + let s = borrow_global_mut(self()); + let operatorApproval = mut_operatorApprovals(s, owner, operator); + *operatorApproval = approved; + emit(ApprovalForAll{account: owner, operator, approved}); + } + + #[callable(sig=b"isApprovedForAll(address,address) returns (bool)"), view] + /// Queries the approval status of an operator for a given owner. + public fun isApprovedForAll(account: address, operator: address): bool acquires State { + let s = borrow_global_mut(self()); + *mut_operatorApprovals(s, account, operator) + } + + #[callable(sig=b"safeTransferFrom(address,address,uint256,uint256,bytes)")] + /// Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + public fun safeTransferFrom(from: address, to: address, id: U256, amount: U256, data: vector) acquires State { + require(to != @0x0, b"ERC1155: transfer to the zero address"); + require(from == sender() || isApprovedForAll(from, sender()), b"ERC1155: caller is not owner nor approved"); + let s = borrow_global_mut(self()); + let mut_balance_from = mut_balanceOf(s, copy id, from); + require(U256::le(copy amount, *mut_balance_from), b"ERC1155: insufficient balance for transfer"); + *mut_balance_from = U256::sub(*mut_balance_from, copy amount); + let mut_balance_to = mut_balanceOf(s, copy id, to); + *mut_balance_to = U256::add(*mut_balance_to, copy amount); + let operator = sender(); + + emit(TransferSingle{operator, from, to, id: copy id, value: copy amount}); + + doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); + } + + #[callable(sig=b"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")] + /// Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + public fun safeBatchTransferFrom(from: address, to: address, ids: vector, amounts: vector, data: vector) acquires State { + require(to != @0x0, b"ERC1155: transfer to the zero address"); + require(from == sender() || isApprovedForAll(from, sender()), b"ERC1155: transfer caller is not owner nor approved"); + require(vector::length(&amounts) == vector::length(&ids), b"ERC1155: ids and amounts length mismatch"); + let len = vector::length(&amounts); + let i = 0; + + let operator = sender(); + let s = borrow_global_mut(self()); + + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_from = mut_balanceOf(s, copy id, from); + require(U256::le(copy amount, *mut_balance_from), b"ERC1155: insufficient balance for transfer"); + *mut_balance_from = U256::sub(*mut_balance_from, copy amount); + let mut_balance_to = mut_balanceOf(s, id, to); + *mut_balance_to = U256::add(*mut_balance_to, amount); + + i = i + 1; + }; + + emit(TransferBatch{operator, from, to, ids: copy ids, values: copy amounts}); + + doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); + } + + #[callable(sig=b"supportsInterface(bytes4) returns (bool)"), view] + // Query if this contract implements a certain interface. + public fun supportsInterface(interfaceId: vector): bool { + interfaceId == IERC165_interfaceId() || interfaceId == IERC1155_interfaceId() + } + + #[callable(sig=b"owner() returns (address)"), view] + public fun owner(): address acquires State { + borrow_global_mut(self()).owner + } + + // Internal function for minting. + fun mint_(to: address, id: U256, amount: U256, _data: vector) acquires State { + require(to != @0x0, b"ERC1155: mint to the zero address"); + let s = borrow_global_mut(self()); + let mut_balance_to = mut_balanceOf(s, copy id, to); + *mut_balance_to = U256::add(*mut_balance_to, copy amount); + emit(TransferSingle{operator: sender(), from: @0x0, to, id: copy id, value: copy amount}); + } + + /// Internal function for mintBatch + fun mintBatch_(to: address, ids: vector, amounts: vector, _data: vector) acquires State { + require(to != @0x0, b"ERC1155: mint to the zero address"); + require(vector::length(&amounts) == vector::length(&ids), b"ERC1155: ids and amounts length mismatch"); + let len = vector::length(&amounts); + let i = 0; + + let s = borrow_global_mut(self()); + + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_to = mut_balanceOf(s, id, to); + *mut_balance_to = U256::add(*mut_balance_to, amount); + + i = i + 1; + }; + emit(TransferBatch{operator: sender(), from: @0x0, to, ids: copy ids, values: copy amounts}); + } + + public fun burn_(owner: address, id: U256, amount: U256) acquires State { + require(owner != @0x0, b"ERC1155: burn from the zero address"); + let s = borrow_global_mut(self()); + let mut_balance_owner = mut_balanceOf(s, id, owner); + require(U256::ge(*mut_balance_owner, amount), b"ERC1155: burn amount exceeds balance"); + *mut_balance_owner = U256::sub(*mut_balance_owner, amount); + emit(TransferSingle{operator: sender(), from: owner, to: @0x0, id, value: amount}); + } + + public fun burnBatch_(owner: address, ids: vector, amounts: vector) acquires State { + require(owner != @0x0, b"ERC1155: burn from the zero address"); + require(vector::length(&amounts) == vector::length(&ids), b"ERC1155: ids and amounts length mismatch"); + let len = vector::length(&amounts); + let i = 0; + let s = borrow_global_mut(self()); + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_owner = mut_balanceOf(s, id, owner); + require(U256::ge(*mut_balance_owner, amount), b"ERC1155: burn amount exceeds balance"); + *mut_balance_owner = U256::sub(*mut_balance_owner, amount); + + i = i + 1; + }; + emit(TransferBatch{operator: sender(), from: owner, to: @0x0, ids, values: amounts}); + } + + + /// Helper function to return a mut ref to the operatorApproval + fun mut_operatorApprovals(s: &mut State, account: address, operator: address): &mut bool { + if(!Table::contains(&s.operatorApprovals, &account)) { + Table::insert( + &mut s.operatorApprovals, + &account, + Table::empty() + ) + }; + let operatorApproval_account = Table::borrow_mut( + &mut s.operatorApprovals, + &account + ); + Table::borrow_mut_with_default(operatorApproval_account, &operator, false) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, id: U256, account: address): &mut U256 { + if(!Table::contains(&s.balances, &id)) { + Table::insert( + &mut s.balances, + &id, + Table::empty() + ) + }; + let balances_id = Table::borrow_mut(&mut s.balances, &id); + Table::borrow_mut_with_default(balances_id, &account, U256::zero()) + } + + /// Helper function for the safe transfer acceptance check. + fun doSafeTransferAcceptanceCheck(operator: address, from: address, to: address, id: U256, amount: U256, data: vector) { + if (isContract(to)) { + let result = IERC1155Receiver_try_call_onERC1155Received(to, operator, from, id, amount, data); + if (ExternalResult::is_err_reason(&result)) { + // abort_with(b"err_reason"); + let reason = ExternalResult::unwrap_err_reason(result); + abort_with(reason); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"ERC1155: transfer to non ERC1155Receiver implementer"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else if (ExternalResult::is_ok(&result)) { + // abort_with(b"ok"); + let retval = ExternalResult::unwrap(result); + let expected = IERC1155Receiver_selector_onERC1155Received(); + require(retval == expected, b"ERC1155: ERC1155Receiver rejected tokens"); + } else { + abort_with(b"other"); + } + } + } + + /// Helper function for the safe batch transfer acceptance check. + fun doSafeBatchTransferAcceptanceCheck(operator: address, from: address, to: address, ids: vector, amounts: vector, data: vector) { + if (isContract(to)) { + let result = IERC1155Receiver_try_call_onERC1155BatchReceived(to, operator, from, ids, amounts, data); + if (ExternalResult::is_err_reason(&result)) { + // abort_with(b"err_reason"); + let reason = ExternalResult::unwrap_err_reason(result); + abort_with(reason); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"ERC1155: transfer to non ERC1155Receiver implementer"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else if (ExternalResult::is_ok(&result)) { + // abort_with(b"ok"); + let retval = ExternalResult::unwrap(result); + let expected = IERC1155Receiver_selector_onERC1155BatchReceived(); + require(retval == expected, b"ERC1155: ERC1155Receiver rejected tokens"); + } else { + abort_with(b"other"); + } + } + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock_Sol.sol b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock_Sol.sol new file mode 100644 index 000000000..300a460e0 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Mock_Sol.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; + +/** + * @title ERC1155Mock + * This mock just publicizes internal functions for testing purposes + */ +contract ERC1155Mock_Sol is ERC1155 { + constructor(string memory uri) ERC1155(uri) {} + + function setURI(string memory newuri) public { + _setURI(newuri); + } + + function mint( + address to, + uint256 id, + uint256 value, + bytes memory data + ) public { + _mint(to, id, value, data); + } + + function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory values, + bytes memory data + ) public { + _mintBatch(to, ids, values, data); + } + + function burn( + address owner, + uint256 id, + uint256 value + ) public { + _burn(owner, id, value); + } + + function burnBatch( + address owner, + uint256[] memory ids, + uint256[] memory values + ) public { + _burnBatch(owner, ids, values); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155ReceiverMock.sol b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155ReceiverMock.sol new file mode 100644 index 000000000..18e68e58f --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155ReceiverMock.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + + +import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +contract ERC1155ReceiverMock is ERC165, IERC1155Receiver { + bytes4 private _recRetval; + bool private _recReverts; + bytes4 private _batRetval; + bool private _batReverts; + + event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas); + event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas); + + constructor( + bytes4 recRetval, + bool recReverts, + bytes4 batRetval, + bool batReverts + ) { + _recRetval = recRetval; + _recReverts = recReverts; + _batRetval = batRetval; + _batReverts = batReverts; + } + + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) external override returns (bytes4) { + require(!_recReverts, "ERC1155ReceiverMock: reverting on receive"); + emit Received(operator, from, id, value, data, gasleft()); + return _recRetval; + } + + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) external override returns (bytes4) { + require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive"); + emit BatchReceived(operator, from, ids, values, data, gasleft()); + return _batRetval; + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Tradable/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Tradable/Move.toml new file mode 100644 index 000000000..ee54facc6 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Tradable/Move.toml @@ -0,0 +1,11 @@ +[package] +name = "ERC1155Tradable" +version = "0.0.0" + +[addresses] +std = "0x1" +Evm = "0x2" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } +MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Tradable/sources/ERC1155Tradable.move b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Tradable/sources/ERC1155Tradable.move new file mode 100644 index 000000000..3988cc418 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC1155Tradable/sources/ERC1155Tradable.move @@ -0,0 +1,466 @@ +#[evm_contract] +/// An implementation of the ERC1155Tradable (https://github.com/ProjectOpenSea/opensea-erc1155/blob/master/contracts/ERC1155Tradable.sol). +module Evm::ERC1155Tradable { + use Evm::Evm::{sender, self, sign, emit, isContract, abort_with, require, tokenURI_with_baseURI}; + use Evm::Table::{Self, Table}; + use Evm::ExternalResult::{Self, ExternalResult}; + use Evm::U256::{Self, U256}; + use std::vector; + + // --------------------- + // For test only + // --------------------- + + #[callable(sig=b"mint(address,uint256,uint256,bytes)")] + public fun mint(to: address, id: U256, amount: U256, data: vector) acquires State { + mint_(to, id, amount, data); + } + + #[callable(sig=b"mintBatch(address,uint256[],uint256[],bytes)")] + public fun mintBatch(to: address, ids: vector, amounts: vector, data: vector) acquires State { + mintBatch_(to, ids, amounts, data); + } + + #[callable(sig=b"burn(address,uint256,uint256)")] + public fun burn(owner: address, id: U256, amount: U256) acquires State { + burn_(owner, id, amount); + } + + #[callable(sig=b"burnBatch(address,uint256[],uint256[])")] + public fun burnBatch(owner: address, ids: vector, amounts: vector) acquires State { + burnBatch_(owner, ids, amounts); + } + + + // --------------------- + // Evm::IERC1155Receiver + // --------------------- + + #[external(sig=b"onERC1155Received(address,address,uint256,uint256,bytes) returns (bytes4)")] + public native fun IERC1155Receiver_try_call_onERC1155Received(contract: address, operator: address, from: address, id: U256, amount: U256, bytes: vector): ExternalResult>; + + #[external(sig=b"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes) returns (bytes4)")] + public native fun IERC1155Receiver_try_call_onERC1155BatchReceived(contract: address, operator: address, from: address, ids: vector, amounts: vector, bytes: vector): ExternalResult>; + + /// Return the selector of the function `onERC1155Received` + public fun IERC1155Receiver_selector_onERC1155Received(): vector { + //bytes4(keccak256(b"onERC1155Received(address,address,uint256,uint256,bytes)")) + x"f23a6e61" + } + + /// Return the selector of the function `onERC1155Received` + public fun IERC1155Receiver_selector_onERC1155BatchReceived(): vector { + //bytes4(keccak256(b"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) + x"bc197c81" + } + + /// Return the interface identifier of this interface. + public fun IERC1155Receiver_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + // bytes_xor( + // IERC1155Receiver_selector_onERC1155Received(), + // IERC1155Receiver_selector_onERC1155BatchReceived() + // ) + //x"4e2312e0" + x"4e2312e1" // TODO: wrong value + } + + // --------------------- + // Evm::IERC165 + // --------------------- + public fun IERC165_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + //bytes4(keccak256(b"supportsInterface(bytes4)")) + x"01ffc9a7" + } + + // --------------------- + // Evm::IERC1155 + // --------------------- + public fun IERC1155_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + //bytes4(keccak256(b"supportsInterface(bytes4)")) + x"d9b67a26" + } + + #[event] + struct TransferSingle { + operator: address, + from: address, + to: address, + id: U256, + value: U256, + } + + #[event] + struct TransferBatch { + operator: address, + from: address, + to: address, + ids: vector, + values: vector, + } + + #[event] + struct ApprovalForAll { + account: address, + operator: address, + approved: bool, + } + + #[event(sig=b"URI(string,uint256)")] + struct URI { + value: vector, + id: U256, + } + + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + name: vector, + symbol: vector, + balances: Table>, + operatorApprovals: Table>, + //uri: vector, + owner: address, // Implements the "ownable" pattern. + baseURI: vector, + creators: Table, + tokenSupply: Table, + currentTokenID: U256, +// proxyRegistryAddress: address; + } + + #[create(sig=b"constructor(string,string,string)")] + /// Constructor of this contract. + public fun constructor(name: vector, symbol: vector, baseURI: vector) acquires State { + // Initial state of contract + move_to( + &sign(self()), + State { + name, + symbol, + balances: Table::empty>(), + operatorApprovals: Table::empty>(), + //uri, + owner: sender(), + baseURI, + creators: Table::empty(), + tokenSupply: Table::empty(), + currentTokenID: U256::zero(), + } + ); + // for deployment test only + // mint(sender(), U256::u256_from_u128(1), U256::u256_from_u128(10), b""); + // mint(sender(), U256::u256_from_u128(2), U256::u256_from_u128(100), b""); + // mint(sender(), U256::u256_from_u128(3), U256::u256_from_u128(1000), b""); + create(sender(), U256::u256_from_u128(10), b"", b""); + create(sender(), U256::u256_from_u128(100), b"", b""); + create(sender(), U256::u256_from_u128(1000), b"", b""); + } + + #[callable(sig=b"uri(uint256) returns (string)"), view] + /// Returns the name of the token + public fun uri(id: U256): vector acquires State { + require(exists_(id), b"ERC1155Tradable#uri: NONEXISTENT_TOKEN"); + tokenURI_with_baseURI(baseURI(), id) + } + + fun exists_(tokenId: U256): bool acquires State { + let s = borrow_global_mut(self()); + *mut_creatorOf(s, tokenId) != @0x0 + } + + #[callable(sig=b"baseURI() returns (string)"), view] + public fun baseURI(): vector acquires State { + let s = borrow_global_mut(self()); + s.baseURI + } + + #[callable(sig=b"name() returns (string)"), view] + public fun name(): vector acquires State { + let s = borrow_global_mut(self()); + s.name + } + + #[callable(sig=b"symbol() returns (string)"), view] + public fun symbol(): vector acquires State { + let s = borrow_global_mut(self()); + s.symbol + } + + + #[callable(sig=b"setBaseMetadataURI(string)")] + public fun setBaseMetadataURI(newBaseURI: vector) acquires State { + let s = borrow_global_mut(self()); + s.baseURI = newBaseURI; + } + + #[callable(sig=b"totalSupply(uint256) returns (uint256)"), view] + public fun totalSupply(tokenId: U256): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_tokenSupplyOf(s, tokenId) + } + + #[callable(sig=b"create(address,uint256,string,bytes) returns (uint256)"), view] + public fun create(initialOwner: address, initialSupply: U256, uri: vector, data: vector): U256 acquires State { + let s = borrow_global_mut(self()); + s.currentTokenID = U256::add(s.currentTokenID, U256::one()); + let id = s.currentTokenID; + *mut_creatorOf(s, id) = sender(); + if (vector::length(&uri) > 0) { + emit(URI{value: uri, id}) + }; + *mut_tokenSupplyOf(s, id) = initialSupply; + mint(initialOwner, id, initialSupply, data); + id + } + + #[callable(sig=b"balanceOf(address,uint256) returns (uint256)"), view] + /// Get the balance of an account's token. + public fun balanceOf(account: address, id: U256): U256 acquires State { + require(account != @0x0, b"ERC1155: balance query for the zero address"); + let s = borrow_global_mut(self()); + *mut_balanceOf(s, id, account) + } + + #[callable(sig=b"balanceOfBatch(address[],uint256[]) returns (uint256[])"), view] + /// Get the balance of multiple account/token pairs. + public fun balanceOfBatch(accounts: vector
, ids: vector): vector acquires State { + require(vector::length(&accounts) == vector::length(&ids), b"ERC1155: accounts and ids length mismatch"); + let len = vector::length(&accounts); + let i = 0; + let balances = vector::empty(); + while(i < len) { + vector::push_back( + &mut balances, + balanceOf( + *vector::borrow(&accounts, i), + *vector::borrow(&ids, i) + ) + ); + i = i + 1; + }; + balances + } + + #[callable(sig=b"setApprovalForAll(address,bool)")] + /// Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. + public fun setApprovalForAll(operator: address, approved: bool) acquires State { + let owner = sender(); + require(owner != operator, b"ERC1155: setting approval status for self"); + let s = borrow_global_mut(self()); + let operatorApproval = mut_operatorApprovals(s, owner, operator); + *operatorApproval = approved; + emit(ApprovalForAll{account: owner, operator, approved}); + } + + #[callable(sig=b"isApprovedForAll(address,address) returns (bool)"), view] + /// Queries the approval status of an operator for a given owner. + public fun isApprovedForAll(account: address, operator: address): bool acquires State { + let s = borrow_global_mut(self()); + *mut_operatorApprovals(s, account, operator) + } + + #[callable(sig=b"safeTransferFrom(address,address,uint256,uint256,bytes)")] + /// Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + public fun safeTransferFrom(from: address, to: address, id: U256, amount: U256, data: vector) acquires State { + require(to != @0x0, b"ERC1155: transfer to the zero address"); + require(from == sender() || isApprovedForAll(from, sender()), b"ERC1155: caller is not owner nor approved"); + let s = borrow_global_mut(self()); + let mut_balance_from = mut_balanceOf(s, copy id, from); + require(U256::le(copy amount, *mut_balance_from), b"ERC1155: insufficient balance for transfer"); + *mut_balance_from = U256::sub(*mut_balance_from, copy amount); + let mut_balance_to = mut_balanceOf(s, copy id, to); + *mut_balance_to = U256::add(*mut_balance_to, copy amount); + let operator = sender(); + + emit(TransferSingle{operator, from, to, id: copy id, value: copy amount}); + + doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); + } + + #[callable(sig=b"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")] + /// Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + public fun safeBatchTransferFrom(from: address, to: address, ids: vector, amounts: vector, data: vector) acquires State { + require(to != @0x0, b"ERC1155: transfer to the zero address"); + require(from == sender() || isApprovedForAll(from, sender()), b"ERC1155: transfer caller is not owner nor approved"); + require(vector::length(&amounts) == vector::length(&ids), b"ERC1155: ids and amounts length mismatch"); + let len = vector::length(&amounts); + let i = 0; + + let operator = sender(); + let s = borrow_global_mut(self()); + + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_from = mut_balanceOf(s, copy id, from); + require(U256::le(copy amount, *mut_balance_from), b"ERC1155: insufficient balance for transfer"); + *mut_balance_from = U256::sub(*mut_balance_from, copy amount); + let mut_balance_to = mut_balanceOf(s, id, to); + *mut_balance_to = U256::add(*mut_balance_to, amount); + + i = i + 1; + }; + + emit(TransferBatch{operator, from, to, ids: copy ids, values: copy amounts}); + + doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); + } + + #[callable(sig=b"supportsInterface(bytes4) returns (bool)"), view] + // Query if this contract implements a certain interface. + public fun supportsInterface(interfaceId: vector): bool { + interfaceId == IERC165_interfaceId() || interfaceId == IERC1155_interfaceId() + } + + #[callable(sig=b"owner() returns (address)"), view] + public fun owner(): address acquires State { + borrow_global_mut(self()).owner + } + + // Internal function for minting. + fun mint_(to: address, id: U256, amount: U256, _data: vector) acquires State { + require(to != @0x0, b"ERC1155: mint to the zero address"); + let s = borrow_global_mut(self()); + let mut_balance_to = mut_balanceOf(s, copy id, to); + *mut_balance_to = U256::add(*mut_balance_to, copy amount); + emit(TransferSingle{operator: sender(), from: @0x0, to, id: copy id, value: copy amount}); + } + + /// Internal function for mintBatch + fun mintBatch_(to: address, ids: vector, amounts: vector, _data: vector) acquires State { + require(to != @0x0, b"ERC1155: mint to the zero address"); + require(vector::length(&amounts) == vector::length(&ids), b"ERC1155: ids and amounts length mismatch"); + let len = vector::length(&amounts); + let i = 0; + + let s = borrow_global_mut(self()); + + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_to = mut_balanceOf(s, id, to); + *mut_balance_to = U256::add(*mut_balance_to, amount); + + i = i + 1; + }; + emit(TransferBatch{operator: sender(), from: @0x0, to, ids: copy ids, values: copy amounts}); + } + + public fun burn_(owner: address, id: U256, amount: U256) acquires State { + require(owner != @0x0, b"ERC1155: burn from the zero address"); + let s = borrow_global_mut(self()); + let mut_balance_owner = mut_balanceOf(s, id, owner); + require(U256::ge(*mut_balance_owner, amount), b"ERC1155: burn amount exceeds balance"); + *mut_balance_owner = U256::sub(*mut_balance_owner, amount); + emit(TransferSingle{operator: sender(), from: owner, to: @0x0, id, value: amount}); + } + + public fun burnBatch_(owner: address, ids: vector, amounts: vector) acquires State { + require(owner != @0x0, b"ERC1155: burn from the zero address"); + require(vector::length(&amounts) == vector::length(&ids), b"ERC1155: ids and amounts length mismatch"); + let len = vector::length(&amounts); + let i = 0; + let s = borrow_global_mut(self()); + while(i < len) { + let id = *vector::borrow(&ids, i); + let amount = *vector::borrow(&amounts, i); + + let mut_balance_owner = mut_balanceOf(s, id, owner); + require(U256::ge(*mut_balance_owner, amount), b"ERC1155: burn amount exceeds balance"); + *mut_balance_owner = U256::sub(*mut_balance_owner, amount); + + i = i + 1; + }; + emit(TransferBatch{operator: sender(), from: owner, to: @0x0, ids, values: amounts}); + } + + + /// Helper function to return a mut ref to the operatorApproval + fun mut_operatorApprovals(s: &mut State, account: address, operator: address): &mut bool { + if(!Table::contains(&s.operatorApprovals, &account)) { + Table::insert( + &mut s.operatorApprovals, + &account, + Table::empty() + ) + }; + let operatorApproval_account = Table::borrow_mut( + &mut s.operatorApprovals, + &account + ); + Table::borrow_mut_with_default(operatorApproval_account, &operator, false) + } + + /// Helper function to return a mut ref to the creator. + fun mut_creatorOf(s: &mut State, id: U256): &mut address { + Table::borrow_mut_with_default(&mut s.creators, &id, @0x0) + } + + /// Helper function to return a mut ref to the tokenSupply. + fun mut_tokenSupplyOf(s: &mut State, id: U256): &mut U256 { + Table::borrow_mut_with_default(&mut s.tokenSupply, &id, U256::zero()) + } + + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, id: U256, account: address): &mut U256 { + if(!Table::contains(&s.balances, &id)) { + Table::insert( + &mut s.balances, + &id, + Table::empty() + ) + }; + let balances_id = Table::borrow_mut(&mut s.balances, &id); + Table::borrow_mut_with_default(balances_id, &account, U256::zero()) + } + + /// Helper function for the safe transfer acceptance check. + fun doSafeTransferAcceptanceCheck(operator: address, from: address, to: address, id: U256, amount: U256, data: vector) { + if (isContract(to)) { + let result = IERC1155Receiver_try_call_onERC1155Received(to, operator, from, id, amount, data); + if (ExternalResult::is_err_reason(&result)) { + // abort_with(b"err_reason"); + let reason = ExternalResult::unwrap_err_reason(result); + abort_with(reason); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"ERC1155: transfer to non ERC1155Receiver implementer"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else if (ExternalResult::is_ok(&result)) { + // abort_with(b"ok"); + let retval = ExternalResult::unwrap(result); + let expected = IERC1155Receiver_selector_onERC1155Received(); + require(retval == expected, b"ERC1155: ERC1155Receiver rejected tokens"); + } else { + abort_with(b"other"); + } + } + } + + /// Helper function for the safe batch transfer acceptance check. + fun doSafeBatchTransferAcceptanceCheck(operator: address, from: address, to: address, ids: vector, amounts: vector, data: vector) { + if (isContract(to)) { + let result = IERC1155Receiver_try_call_onERC1155BatchReceived(to, operator, from, ids, amounts, data); + if (ExternalResult::is_err_reason(&result)) { + // abort_with(b"err_reason"); + let reason = ExternalResult::unwrap_err_reason(result); + abort_with(reason); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"ERC1155: transfer to non ERC1155Receiver implementer"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else if (ExternalResult::is_ok(&result)) { + // abort_with(b"ok"); + let retval = ExternalResult::unwrap(result); + let expected = IERC1155Receiver_selector_onERC1155BatchReceived(); + require(retval == expected, b"ERC1155: ERC1155Receiver rejected tokens"); + } else { + abort_with(b"other"); + } + } + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock/Move.toml new file mode 100644 index 000000000..2140b03a2 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "ERC20DecimalsMock" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock/sources/ERC20DecimalsMock.move b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock/sources/ERC20DecimalsMock.move new file mode 100644 index 000000000..b6f357136 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock/sources/ERC20DecimalsMock.move @@ -0,0 +1,203 @@ +#[evm_contract] +/// An implementation of the ERC-20 Token Standard. +module Evm::ERC20DecimalsMock { + use Evm::Evm::{sender, self, sign, emit, require}; + use Evm::Table::{Self, Table}; + use Evm::U256::{Self, U256}; + + #[event(sig=b"Transfer(address indexed,address indexed,uint256)")] + struct Transfer { + from: address, + to: address, + value: U256, + } + + #[event(sig=b"Approval(address indexed,address indexed,uint256)")] + struct Approval { + owner: address, + spender: address, + value: U256, + } + + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + balances: Table, + allowances: Table>, + total_supply: U256, + name: vector, + symbol: vector, + decimals: u8, + } + + #[create(sig=b"constructor(string,string,uint8)")] + /// Constructor of this contract. + public fun create(name: vector, symbol: vector, decimals: u8) { + // Initial state of contract + move_to( + &sign(self()), + State { + total_supply: U256::zero(), + balances: Table::empty(), + allowances: Table::empty>(), + name, + symbol, + decimals, + } + ); + } + + #[callable(sig=b"name() returns (string)"), view] + /// Returns the name of the token + public fun name(): vector acquires State { + *&borrow_global(self()).name + } + + #[callable(sig=b"symbol() returns (string)"), view] + /// Returns the symbol of the token, usually a shorter version of the name. + public fun symbol(): vector acquires State { + *&borrow_global(self()).symbol + } + + #[callable(sig=b"decimals() returns (uint8)"), view] + /// Returns the number of decimals used to get its user representation. + public fun decimals(): u8 acquires State { + *&borrow_global(self()).decimals + } + + #[callable(sig=b"totalSupply() returns (uint256)"), view] + /// Returns the total supply of the token. + public fun totalSupply(): U256 acquires State { + *&borrow_global(self()).total_supply + } + + #[callable(sig=b"balanceOf(address) returns (uint256)"), view] + /// Returns the balance of an account. + public fun balanceOf(owner: address): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_balanceOf(s, owner) + } + + #[callable(sig=b"transfer(address,uint256) returns (bool)")] + /// Transfers the amount from the sending account to the given account + public fun transfer(to: address, amount: U256): bool acquires State { + transfer_(sender(), to, amount); + true + } + + #[callable(sig=b"transferFrom(address,address,uint256) returns (bool)")] + /// Transfers the amount on behalf of the `from` account to the given account. + /// This evaluates and adjusts the allowance. + public fun transferFrom(from: address, to: address, amount: U256): bool acquires State { + spendAllowance_(from, sender(), amount); + transfer_(from, to, amount); + true + } + + #[callable(sig=b"approve(address,uint256) returns (bool)")] + /// Approves that the spender can spent the given amount on behalf of the calling account. + public fun approve(spender: address, amount: U256): bool acquires State { + approve_(sender(), spender, amount); + true + } + + #[callable(sig=b"allowance(address,address) returns (uint256)"), view] + /// Returns the allowance an account owner has approved for the given spender. + public fun allowance(owner: address, spender: address): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_allowance(s, owner, spender) + } + + #[callable(sig=b"increaseAllowance(address,uint256) returns (bool)")] + /// Atomically increases the allowance granted to `spender` by the caller. + public fun increaseAllowance(spender: address, addedValue: U256): bool acquires State { + let owner = sender(); + approve_(owner, spender, U256::add(allowance(owner, spender), addedValue)); + true + } + + #[callable(sig=b"decreaseAllowance(address,uint256) returns (bool)")] + /// Atomically decreases the allowance granted to `spender` by the caller. + public fun decreaseAllowance(spender: address, subtractedValue: U256): bool acquires State { + let owner = sender(); + let currentAllowance = allowance(owner, spender); + require(U256::ge(currentAllowance, subtractedValue), b"ERC20: decreased allowance below zero"); + approve_(owner, spender, U256::sub(currentAllowance, subtractedValue)); + true + } + + /// Helper function to update `owner` s allowance for `spender` based on spent `amount`. + fun spendAllowance_(owner: address, spender: address, amount: U256) acquires State { + let currentAllowance = allowance(owner, spender); + if (currentAllowance != U256::max()) { + require(U256::ge(currentAllowance, amount), b"ERC20: insufficient allowance"); + approve_(owner, spender, U256::sub(currentAllowance, amount)); + } + } + + /// Helper function to perform an approval + fun approve_(owner: address, spender: address, amount: U256) acquires State { + require(owner != @0x0, b"ERC20: approve from the zero address"); + require(spender != @0x0, b"ERC20: approve to the zero address"); + let s = borrow_global_mut(self()); + if(!Table::contains(&s.allowances, &owner)) { + Table::insert(&mut s.allowances, &owner, Table::empty()) + }; + let a = Table::borrow_mut(&mut s.allowances, &owner); + if(!Table::contains(a, &spender)) { + Table::insert(a, &spender, amount); + } + else { + *Table::borrow_mut(a, &spender) = amount; + }; + emit(Approval{owner, spender, value: amount}); + } + + /// Helper function to perform a transfer of funds. + fun transfer_(from: address, to: address, amount: U256) acquires State { + require(from != @0x0, b"ERC20: transfer from the zero address"); + require(to != @0x0, b"ERC20: transfer to the zero address"); + let s = borrow_global_mut(self()); + let from_bal = mut_balanceOf(s, from); + require(U256::le(copy amount, *from_bal), b"ERC20: transfer amount exceeds balance"); + *from_bal = U256::sub(*from_bal, copy amount); + let to_bal = mut_balanceOf(s, to); + *to_bal = U256::add(*to_bal, copy amount); + emit(Transfer{from, to, value: amount}); + } + + /// Helper function to return a mut ref to the allowance of a spender. + fun mut_allowance(s: &mut State, owner: address, spender: address): &mut U256 { + if(!Table::contains(&s.allowances, &owner)) { + Table::insert(&mut s.allowances, &owner, Table::empty()) + }; + let allowance_owner = Table::borrow_mut(&mut s.allowances, &owner); + Table::borrow_mut_with_default(allowance_owner, &spender, U256::zero()) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, owner: address): &mut U256 { + Table::borrow_mut_with_default(&mut s.balances, &owner, U256::zero()) + } + + /// Create `amount` tokens and assigns them to `account`, increasing + /// the total supply. + fun mint_(account: address, amount: U256) acquires State { + require(account != @0x0, b"ERC20: mint to the zero address"); + let s = borrow_global_mut(self()); + s.total_supply = U256::add(s.total_supply, amount); + let mut_bal_account = mut_balanceOf(s, account); + *mut_bal_account = U256::add(*mut_bal_account, amount); + emit(Transfer{from: @0x0, to: account, value: amount}); + } + + /// Destroys `amount` tokens from `account`, reducing the total supply. + fun burn_(account: address, amount: U256) acquires State { + require(account != @0x0, b"ERC20: burn from the zero address"); + let s = borrow_global_mut(self()); + let mut_bal_account = mut_balanceOf(s, account); + require(U256::ge(*mut_bal_account, amount), b"ERC20: burn amount exceeds balance"); + *mut_bal_account = U256::sub(*mut_bal_account, amount); + s.total_supply = U256::sub(s.total_supply, amount); + emit(Transfer{from: account, to: @0x0, value: amount}); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock_Sol.sol b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock_Sol.sol new file mode 100644 index 000000000..c98c40508 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20DecimalsMock_Sol.sol @@ -0,0 +1,29 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +// mock class using ERC20 +contract ERC20DecimalsMock_Sol is ERC20 { + uint8 private immutable _decimals; + + constructor( + string memory name, + string memory symbol, + uint8 decimals_ + ) payable ERC20(name, symbol) { + _decimals = decimals_; + } + + function decimals() public view virtual override returns (uint8) { + return _decimals; + } + + function mint(address account, uint256 amount) public { + _mint(account, amount); + } + + function burn(address account, uint256 amount) public { + _burn(account, amount); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock/Move.toml new file mode 100644 index 000000000..c52b49046 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "ERC20Mock" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock/sources/ERC20Mock.move b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock/sources/ERC20Mock.move new file mode 100644 index 000000000..1fdeb475c --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock/sources/ERC20Mock.move @@ -0,0 +1,223 @@ +#[evm_contract] +/// An implementation of the ERC-20 Token Standard. +module Evm::ERC20Mock { + use Evm::Evm::{sender, emit, require}; + use Evm::Table::{Self, Table}; + use Evm::U256::{Self, U256}; + + #[event(sig=b"Transfer(address indexed,address indexed,uint256)")] + struct Transfer { + from: address, + to: address, + value: U256, + } + + #[event(sig=b"Approval(address indexed,address indexed,uint256)")] + struct Approval { + owner: address, + spender: address, + value: U256, + } + + #[storage] + /// Represents the state of this contract. + struct State has key { + balances: Table, + allowances: Table>, + total_supply: U256, + name: vector, + symbol: vector, + } + + // ---------------------------------------- + // For test only + // ---------------------------------------- + #[callable(sig=b"mint(address,uint256)")] + public fun mint(state: &mut State, account: address, amount: U256) { + mint_(state, account, amount) + } + + #[callable(sig=b"burn(address,uint256)")] + public fun burn(state: &mut State, account: address, amount: U256) { + burn_(state, account, amount) + } + + #[callable(sig=b"transferInternal(address,address,uint256)")] + public fun transferInternal(state: &mut State, from: address, to: address, value: U256) { + transfer_(state, from, to, value) + } + + #[callable(sig=b"approveInternal(address,address,uint256)")] + public fun approveInternal(state: &mut State, owner: address, spender: address, value: U256) { + approve_(state, owner, spender, value) + } + // ---------------------------------------- + // End of "For test only" + // ---------------------------------------- + + #[create(sig=b"constructor(string,string,address,uint256)")] + /// Constructor of this contract. + public fun create(name: vector, symbol: vector, initial_account: address, initial_balance: U256): State { + // Initial state of contract + let state = State { + total_supply: U256::zero(), + balances: Table::empty(), + allowances: Table::empty>(), + name, + symbol, + }; + // Minting the initial supply + mint_(&mut state, initial_account, initial_balance); + state + } + + #[callable(sig=b"name() returns (string)"), view] + /// Returns the name of the token + public fun name(state: &State): vector { + state.name + } + + #[callable(sig=b"symbol() returns (string)"), view] + /// Returns the symbol of the token, usually a shorter version of the name. + public fun symbol(state: &State): vector { + state.symbol + } + + #[callable(sig=b"decimals() returns (uint8)"), view] + /// Returns the number of decimals used to get its user representation. + public fun decimals(): u8 { + 18 + } + + #[callable(sig=b"totalSupply() returns (uint256)"), view] + /// Returns the total supply of the token. + public fun totalSupply(state: &State): U256 { + state.total_supply + } + + #[callable(sig=b"balanceOf(address) returns (uint256)"), view] + /// Returns the balance of an account. + public fun balanceOf(state: &mut State, owner: address): U256 { + *mut_balanceOf(state, owner) + } + + #[callable(sig=b"transfer(address,uint256) returns (bool)")] + /// Transfers the amount from the sending account to the given account + public fun transfer(state: &mut State, to: address, amount: U256): bool { + transfer_(state, sender(), to, amount); + true + } + + #[callable(sig=b"transferFrom(address,address,uint256) returns (bool)")] + /// Transfers the amount on behalf of the `from` account to the given account. + /// This evaluates and adjusts the allowance. + public fun transferFrom(state: &mut State, from: address, to: address, amount: U256): bool { + spendAllowance_(state, from, sender(), amount); + transfer_(state, from, to, amount); + true + } + + #[callable(sig=b"approve(address,uint256) returns (bool)")] + /// Approves that the spender can spent the given amount on behalf of the calling account. + public fun approve(state: &mut State, spender: address, amount: U256): bool { + approve_(state, sender(), spender, amount); + true + } + + #[callable(sig=b"allowance(address,address) returns (uint256)"), view] + /// Returns the allowance an account owner has approved for the given spender. + public fun allowance(state: &mut State, owner: address, spender: address): U256 { + *mut_allowance(state, owner, spender) + } + + #[callable(sig=b"increaseAllowance(address,uint256) returns (bool)")] + /// Atomically increases the allowance granted to `spender` by the caller. + public fun increaseAllowance(state: &mut State, spender: address, addedValue: U256): bool { + let owner = sender(); + let increased = U256::add(allowance(state, owner, spender), addedValue); + approve_(state, owner, spender, increased); + true + } + + #[callable(sig=b"decreaseAllowance(address,uint256) returns (bool)")] + /// Atomically decreases the allowance granted to `spender` by the caller. + public fun decreaseAllowance(state: &mut State, spender: address, subtractedValue: U256): bool { + let owner = sender(); + let currentAllowance = allowance(state, owner, spender); + require(U256::ge(currentAllowance, subtractedValue), b"ERC20: decreased allowance below zero"); + approve_(state, owner, spender, U256::sub(currentAllowance, subtractedValue)); + true + } + + /// Helper function to update `owner` s allowance for `spender` based on spent `amount`. + fun spendAllowance_(state: &mut State, owner: address, spender: address, amount: U256) { + let currentAllowance = allowance(state, owner, spender); + if (currentAllowance != U256::max()) { + require(U256::ge(currentAllowance, amount), b"ERC20: insufficient allowance"); + approve_(state, owner, spender, U256::sub(currentAllowance, amount)); + } + } + + /// Helper function to perform an approval + fun approve_(state: &mut State, owner: address, spender: address, amount: U256) { + require(owner != @0x0, b"ERC20: approve from the zero address"); + require(spender != @0x0, b"ERC20: approve to the zero address"); + if(!Table::contains(&state.allowances, &owner)) { + Table::insert(&mut state.allowances, &owner, Table::empty()) + }; + let a = Table::borrow_mut(&mut state.allowances, &owner); + if(!Table::contains(a, &spender)) { + Table::insert(a, &spender, amount); + } + else { + *Table::borrow_mut(a, &spender) = amount; + }; + emit(Approval{owner, spender, value: amount}); + } + + /// Helper function to perform a transfer of funds. + fun transfer_(state: &mut State, from: address, to: address, amount: U256) { + require(from != @0x0, b"ERC20: transfer from the zero address"); + require(to != @0x0, b"ERC20: transfer to the zero address"); + let from_bal = mut_balanceOf(state, from); + require(U256::le(amount, *from_bal), b"ERC20: transfer amount exceeds balance"); + *from_bal = U256::sub(*from_bal, amount); + let to_bal = mut_balanceOf(state, to); + *to_bal = U256::add(*to_bal, copy amount); + emit(Transfer{from, to, value: amount}); + } + + /// Helper function to return a mut ref to the allowance of a spender. + fun mut_allowance(state: &mut State, owner: address, spender: address): &mut U256 { + if(!Table::contains(&state.allowances, &owner)) { + Table::insert(&mut state.allowances, &owner, Table::empty()) + }; + let allowance_owner = Table::borrow_mut(&mut state.allowances, &owner); + Table::borrow_mut_with_default(allowance_owner, &spender, U256::zero()) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(state: &mut State, owner: address): &mut U256 { + Table::borrow_mut_with_default(&mut state.balances, &owner, U256::zero()) + } + + /// Create `amount` tokens and assigns them to `account`, increasing + /// the total supply. + fun mint_(state: &mut State, account: address, amount: U256) { + require(account != @0x0, b"ERC20: mint to the zero address"); + state.total_supply = U256::add(state.total_supply, amount); + let mut_bal_account = mut_balanceOf(state, account); + *mut_bal_account = U256::add(*mut_bal_account, amount); + emit(Transfer{from: @0x0, to: account, value: amount}); + } + + /// Destroys `amount` tokens from `account`, reducing the total supply. + fun burn_(state: &mut State, account: address, amount: U256) { + require(account != @0x0, b"ERC20: burn from the zero address"); + let mut_bal_account = mut_balanceOf(state, account); + require(U256::ge(*mut_bal_account, amount), b"ERC20: burn amount exceeds balance"); + *mut_bal_account = U256::sub(*mut_bal_account, amount); + state.total_supply = U256::sub(state.total_supply, amount); + emit(Transfer{from: account, to: @0x0, value: amount}); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock_Sol.sol b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock_Sol.sol new file mode 100644 index 000000000..56f7c7d15 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC20Mock_Sol.sol @@ -0,0 +1,40 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +// mock class using ERC20 +contract ERC20Mock_Sol is ERC20 { + constructor( + string memory name, + string memory symbol, + address initialAccount, + uint256 initialBalance + ) payable ERC20(name, symbol) { + _mint(initialAccount, initialBalance); + } + + function mint(address account, uint256 amount) public { + _mint(account, amount); + } + + function burn(address account, uint256 amount) public { + _burn(account, amount); + } + + function transferInternal( + address from, + address to, + uint256 value + ) public { + _transfer(from, to, value); + } + + function approveInternal( + address owner, + address spender, + uint256 value + ) public { + _approve(owner, spender, value); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock/Move.toml new file mode 100644 index 000000000..58d6786a1 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock/Move.toml @@ -0,0 +1,11 @@ +[package] +name = "ERC721Mock" +version = "0.0.0" + +[addresses] +std = "0x1" +Evm = "0x2" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } +MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock/sources/ERC721Mock.move b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock/sources/ERC721Mock.move new file mode 100644 index 000000000..4b92e421b --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock/sources/ERC721Mock.move @@ -0,0 +1,366 @@ +#[evm_contract] +/// An implementation of the ERC-721 Non-Fungible Token Standard. +module Evm::ERC721 { + use Evm::Evm::{sender, self, sign, emit, isContract, tokenURI_with_baseURI, require, abort_with}; + use Evm::ExternalResult::{Self, ExternalResult}; + use Evm::Table::{Self, Table}; + use Evm::U256::{Self, U256}; + use std::vector; + + // --------------------- + // Evm::IERC165 + // --------------------- + public fun IERC165_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + //bytes4(keccak256(b"supportsInterface(bytes4)")) + x"01ffc9a7" + } + + // --------------------- + // Evm::IERC721 + // --------------------- + public fun IERC721_interfaceId(): vector { + x"80ac58cd" + } + + // --------------------- + // Evm::IERC721Metadata + // --------------------- + public fun IERC721Metadata_interfaceId(): vector { + x"5b5e139f" + } + + // --------------------- + // Evm::IERC721Receiver + // --------------------- + public fun IERC721Receiver_selector_onERC721Received(): vector { + x"150b7a02" + } + + // --------------------- + // For test only + // --------------------- + + #[callable] + public fun mint(to: address, tokenId: U256) acquires State { + mint_(to, tokenId); + } + + #[callable(sig=b"safeMint(address,uint256)")] + fun safeMint(to: address, tokenId: U256) acquires State { + safeMint_(to, tokenId, b""); + } + + #[callable(sig=b"safeMint(address,uint256,bytes)")] + fun safeMint_with_data(to: address, tokenId: U256, data: vector) acquires State { + safeMint_(to, tokenId, data); + } + + fun mint_(to: address, tokenId: U256) acquires State { + require(to != @0x0, b"ERC721: mint to the zero address"); + require(!exists_(tokenId), b"ERC721: token already minted"); + + let s = borrow_global_mut(self()); + let mut_balance_to = mut_balanceOf(s, to); + *mut_balance_to = U256::add(*mut_balance_to, U256::one()); + + let mut_ownerOf_to = mut_ownerOf(s, tokenId); + *mut_ownerOf_to = to; + + emit(Transfer{from: @0x0, to, tokenId}); + } + + fun safeMint_(to: address, tokenId: U256, data: vector) acquires State { + mint_(to, tokenId); + doSafeTransferAcceptanceCheck(@0x0, to, tokenId, data); + } + + #[callable] + public fun burn(tokenId: U256) acquires State { + burn_(tokenId); + } + + fun burn_(tokenId: U256) acquires State { + let owner = ownerOf(tokenId); + approve(@0x0, tokenId); + let s = borrow_global_mut(self()); + let mut_balance_owner = mut_balanceOf(s, owner); + *mut_balance_owner = U256::sub(*mut_balance_owner, U256::one()); + let _ = Table::remove(&mut s.owners, &tokenId); + emit(Transfer{from: owner, to: @0x0, tokenId}); + } + + fun exists_(tokenId: U256): bool acquires State { + let s = borrow_global_mut(self()); + tokenExists(s, tokenId) + } + + // Disabled this for a fair gas comparison with `ERC721Mock_Sol.sol` + // which does not support `setBaseURI`. + // #[callable(sig=b"setBaseURI(string)")] + // public fun setBaseURI(newBaseURI: vector) acquires State { + // let s = borrow_global_mut(self()); + // s.baseURI = newBaseURI; + // } + + #[callable(sig=b"baseURI() returns (string)"), view] + public fun baseURI(): vector acquires State { + let s = borrow_global_mut(self()); + s.baseURI + } + + #[event] + struct Transfer { + from: address, + to: address, + tokenId: U256, + } + + #[event] + struct Approval { + owner: address, + approved: address, + tokenId: U256, + } + + #[event] + struct ApprovalForAll { + owner: address, + operator: address, + approved: bool, + } + + /// Represents the state of this contract. + /// This is located at `borrow_global(self())`. + struct State has key { + name: vector, + symbol: vector, + owners: Table, + balances: Table, + tokenApprovals: Table, + operatorApprovals: Table>, + baseURI: vector, + } + + #[create(sig=b"constructor(string,string)")] + /// Constructor of this contract. + public fun create(name: vector, symbol: vector) { + // Initial state of contract + move_to( + &sign(self()), + State { + name, + symbol, + owners: Table::empty(), + balances: Table::empty(), + tokenApprovals: Table::empty(), + operatorApprovals: Table::empty>(), + baseURI: b"", + } + ); + } + + #[callable(sig=b"supportsInterface(bytes4) returns (bool)"), pure] + // Query if this contract implements a certain interface. + public fun supportsInterface(interfaceId: vector): bool { + interfaceId == IERC165_interfaceId() || + interfaceId == IERC721_interfaceId() || + interfaceId == IERC721Metadata_interfaceId() + } + + #[callable(sig=b"name() returns (string)"), view] + /// Get the name. + public fun name(): vector acquires State { + let s = borrow_global(self()); + *&s.name + } + + #[callable(sig=b"symbol() returns (string)"), view] + /// Get the symbol. + public fun symbol(): vector acquires State { + let s = borrow_global(self()); + *&s.symbol + } + + #[callable(sig=b"tokenURI(uint256) returns (string)"), view] + /// Get the name. + public fun tokenURI(tokenId: U256): vector acquires State { + require(exists_(tokenId), b"ERC721Metadata: URI query for nonexistent token"); + tokenURI_with_baseURI(baseURI(), tokenId) + } + + /// Count all NFTs assigned to an owner. + + #[callable(sig=b"balanceOf(address) returns (uint256)"), view] + public fun balanceOf(owner: address): U256 acquires State { + require(owner != @0x0, b"ERC721: balance query for the zero address"); + let s = borrow_global_mut(self()); + *mut_balanceOf(s, owner) + } + + #[callable(sib=b"ownerOf(uint256) returns (address)"), view] + /// Find the owner of an NFT. + public fun ownerOf(tokenId: U256): address acquires State { + require(exists_(tokenId), b"ERC721: owner query for nonexistent token"); + let s = borrow_global_mut(self()); + *mut_ownerOf(s, tokenId) + } + + #[callable(sig=b"safeTransferFrom(address,address,uint256,bytes)")] // Overloading `safeTransferFrom` + /// Transfers the ownership of an NFT from one address to another address. + public fun safeTransferFrom_with_data(from: address, to: address, tokenId: U256, data: vector) acquires State { + transferFrom(from, to, tokenId); + doSafeTransferAcceptanceCheck(from, to, tokenId, data); + } + + #[callable(sig=b"safeTransferFrom(address,address,uint256)")] + /// Transfers the ownership of an NFT from one address to another address. + public fun safeTransferFrom(from: address, to: address, tokenId: U256) acquires State { + safeTransferFrom_with_data(from, to, tokenId, b""); + } + + #[callable] + /// Transfer ownership of an NFT. THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + public fun transferFrom(from: address, to: address, tokenId: U256) acquires State { + require(isApprovedOrOwner(sender(), tokenId), b"ERC721: transfer caller is not owner nor approved"); + + require(ownerOf(tokenId) == from, b"ERC721: transfer from incorrect owner"); + require(to != @0x0, b"ERC721: transfer to the zero address"); + + // Clear approvals from the previous owner + approve_(@0x0, tokenId); + + let s = borrow_global_mut(self()); + + let mut_balance_from = mut_balanceOf(s, from); + *mut_balance_from = U256::sub(*mut_balance_from, U256::one()); + + let mut_balance_to = mut_balanceOf(s, to); + *mut_balance_to = U256::add(*mut_balance_to, U256::one()); + + let mut_owner_token = mut_ownerOf(s, tokenId); + *mut_owner_token = to; + + emit(Transfer{from, to, tokenId}); + } + + #[callable] + /// Change or reaffirm the approved address for an NFT. + public fun approve(approved: address, tokenId: U256) acquires State { + let owner = ownerOf(tokenId); + require(approved != owner, b"ERC721: approval to current owner"); + require((sender() == owner) || isApprovedForAll(owner, sender()), b"ERC721: approve caller is not owner nor approved for all"); + approve_(approved, tokenId); + } + + fun approve_(approved: address, tokenId: U256) acquires State { + let s = borrow_global_mut(self()); + *mut_tokenApproval(s, tokenId) = approved; + emit(Approval{owner: ownerOf(tokenId), approved, tokenId}) + } + + #[callable] + /// Enable or disable approval for a third party ("operator") to manage + /// all of the sender's assets. + public fun setApprovalForAll(operator: address, approved: bool) acquires State { + setApprovalForAll_(sender(), operator, approved); + } + + fun setApprovalForAll_(owner: address, operator: address, approved: bool) acquires State { + require(owner != operator, b"ERC721: approve to caller"); + let s = borrow_global_mut(self()); + *mut_operatorApproval(s, owner, operator) = approved; + emit(ApprovalForAll{owner, operator, approved}) + } + + #[callable, view] + /// Get the approved address for a single NFT. + public fun getApproved(tokenId: U256): address acquires State { + let s = borrow_global_mut(self()); + require(tokenExists(s, tokenId), b"ERC721: approved query for nonexistent token"); + *mut_tokenApproval(s, tokenId) + } + + #[callable, view] + /// Query if an address is an authorized operator for another address. + public fun isApprovedForAll(owner: address, operator: address): bool acquires State { + let s = borrow_global_mut(self()); + *mut_operatorApproval(s, owner, operator) + } + + /// Helper function to return true iff `spender` is the owner or an approved one for `tokenId`. + fun isApprovedOrOwner(spender: address, tokenId: U256): bool acquires State { + let s = borrow_global_mut(self()); + require(tokenExists(s, tokenId), b"ERC721: operator query for nonexistent token"); + let owner = ownerOf(tokenId); + return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, owner: address): &mut U256 { + Table::borrow_mut_with_default(&mut s.balances, &owner, U256::zero()) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_ownerOf(s: &mut State, tokenId: U256): &mut address { + Table::borrow_mut_with_default(&mut s.owners, &tokenId, @0x0) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_tokenApproval(s: &mut State, tokenId: U256): &mut address { + Table::borrow_mut_with_default(&mut s.tokenApprovals, &tokenId, @0x0) + } + + /// Helper function to return a mut ref to the operator approval. + fun mut_operatorApproval(s: &mut State, owner: address, operator: address): &mut bool { + if(!Table::contains(&s.operatorApprovals, &owner)) { + Table::insert( + &mut s.operatorApprovals, + &owner, + Table::empty() + ) + }; + let approvals = Table::borrow_mut(&mut s.operatorApprovals, &owner); + Table::borrow_mut_with_default(approvals, &operator, false) + } + + /// Helper function to return true iff the token exists. + fun tokenExists(s: &mut State, tokenId: U256): bool { + let mut_ownerOf_tokenId = mut_ownerOf(s, tokenId); + *mut_ownerOf_tokenId != @0x0 + } + + /// Helper function for the acceptance check. + fun doSafeTransferAcceptanceCheck(from: address, to: address, tokenId: U256, data: vector) { + if (isContract(to)) { + let result = IERC721Receiver_try_call_onERC721Received(to, sender(), from, tokenId, data); + if (ExternalResult::is_err_reason(&result)) { + // abort_with(b"err_reason"); + let reason = ExternalResult::unwrap_err_reason(result); + abort_with(reason); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"ERC721: transfer to non ERC721Receiver implementer"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else if (ExternalResult::is_ok(&result)) { + // abort_with(b"ok"); + let retval = ExternalResult::unwrap(result); + let expected = IERC721Receiver_selector_onERC721Received(); + require(retval == expected, b"ERC721: transfer to non ERC721Receiver implementer"); + } else { + abort_with(b"other"); + } + } + } + + #[external(sig=b"onERC721Received(address,address,uint256,bytes) returns (bytes4)")] + public native fun IERC721Receiver_try_call_onERC721Received( + contract: address, + operator: address, + from: address, + tokenId: U256, + bytes: vector + ): ExternalResult>; +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock_Sol.sol b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock_Sol.sol new file mode 100644 index 000000000..e4c7f03cb --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Mock_Sol.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; + +/** + * @title ERC721Mock + * This mock just provides a public safeMint, mint, and burn functions for testing purposes + */ +contract ERC721Mock_Sol is ERC721 { + constructor(string memory name, string memory symbol) ERC721(name, symbol) {} + + function baseURI() public view returns (string memory) { + return _baseURI(); + } + + function exists(uint256 tokenId) public view returns (bool) { + return _exists(tokenId); + } + + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } + + function safeMint(address to, uint256 tokenId) public { + _safeMint(to, tokenId); + } + + function safeMint( + address to, + uint256 tokenId, + bytes memory _data + ) public { + _safeMint(to, tokenId, _data); + } + + function burn(uint256 tokenId) public { + _burn(tokenId); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC721ReceiverMock.sol b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721ReceiverMock.sol new file mode 100644 index 000000000..e1885b045 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721ReceiverMock.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "hardhat/console.sol"; + + +contract ERC721ReceiverMock is IERC721Receiver { + enum Error { + None, + RevertWithMessage, + RevertWithoutMessage, + Panic + } + + bytes4 private immutable _retval; + Error private immutable _error; + + event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas); + + constructor(bytes4 retval, Error error) { + _retval = retval; + _error = error; + } + + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes memory data + ) public override returns (bytes4) { + if (_error == Error.RevertWithMessage) { + // console.log('RevertWithMessage'); + revert("ERC721ReceiverMock: reverting"); + } else if (_error == Error.RevertWithoutMessage) { + // console.log('RevertWithoutMessage'); + revert(); + } else if (_error == Error.Panic) { + // console.log('Panic'); + uint256 a = uint256(0) / uint256(0); + a; + } + emit Received(operator, from, tokenId, data, gasleft()); + //console.log('Ok'); + return _retval; + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable/Move.toml new file mode 100644 index 000000000..0c8b6d3be --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable/Move.toml @@ -0,0 +1,11 @@ +[package] +name = "ERC721Tradable" +version = "0.0.0" + +[addresses] +std = "0x1" +Evm = "0x2" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } +MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable/sources/ERC721Tradable.move b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable/sources/ERC721Tradable.move new file mode 100644 index 000000000..8f942552c --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable/sources/ERC721Tradable.move @@ -0,0 +1,368 @@ +#[evm_contract] +/// An implementation of the ERC-721 Non-Fungible Token Standard. +module Evm::ERC721Tradable { + use Evm::Evm::{sender, self, sign, emit, isContract, tokenURI_with_baseURI, require, abort_with}; + use Evm::ExternalResult::{Self, ExternalResult}; + use Evm::Table::{Self, Table}; + use Evm::U256::{Self, U256}; + + // --------------------- + // Evm::IERC165 + // --------------------- + public fun IERC165_interfaceId(): vector { + // TODO: Eager evaulate this at the compile time for optimization. + //bytes4(keccak256(b"supportsInterface(bytes4)")) + x"01ffc9a7" + } + + // --------------------- + // Evm::IERC721 + // --------------------- + public fun IERC721_interfaceId(): vector { + x"80ac58cd" + } + + // --------------------- + // Evm::IERC721Metadata + // --------------------- + public fun IERC721Metadata_interfaceId(): vector { + x"5b5e139f" + } + + // --------------------- + // Evm::IERC721Receiver + // --------------------- + public fun IERC721Receiver_selector_onERC721Received(): vector { + x"150b7a02" + } + + // --------------------- + // For test only + // --------------------- + + #[callable] + public fun mint(to: address, tokenId: U256) acquires State { + mint_(to, tokenId); + } + + #[callable(sig=b"safeMint(address,uint256)")] + fun safeMint(to: address, tokenId: U256) acquires State { + safeMint_(to, tokenId, b""); + } + + #[callable(sig=b"safeMint(address,uint256,bytes)")] + fun safeMint_with_data(to: address, tokenId: U256, data: vector) acquires State { + safeMint_(to, tokenId, data); + } + + #[callable] + public fun mintTo(to: address) acquires State { + let s = borrow_global_mut(self()); + s.currentTokenID = U256::add(s.currentTokenID, U256::one()); + mint_(to, s.currentTokenID); + } + + fun mint_(to: address, tokenId: U256) acquires State { + require(to != @0x0, b"ERC721: mint to the zero address"); + require(!exists_(tokenId), b"ERC721: token already minted"); + + let s = borrow_global_mut(self()); + let mut_balance_to = mut_balanceOf(s, to); + *mut_balance_to = U256::add(*mut_balance_to, U256::one()); + + let mut_ownerOf_to = mut_ownerOf(s, tokenId); + *mut_ownerOf_to = to; + + emit(Transfer{from: @0x0, to, tokenId}); + } + + fun safeMint_(to: address, tokenId: U256, data: vector) acquires State { + mint_(to, tokenId); + doSafeTransferAcceptanceCheck(@0x0, to, tokenId, data); + } + + #[callable] + public fun burn(tokenId: U256) acquires State { + burn_(tokenId); + } + + fun burn_(tokenId: U256) acquires State { + let owner = ownerOf(tokenId); + approve(@0x0, tokenId); + let s = borrow_global_mut(self()); + let mut_balance_owner = mut_balanceOf(s, owner); + *mut_balance_owner = U256::sub(*mut_balance_owner, U256::one()); + let _ = Table::remove(&mut s.owners, &tokenId); + emit(Transfer{from: owner, to: @0x0, tokenId}); + } + + fun exists_(tokenId: U256): bool acquires State { + let s = borrow_global_mut(self()); + tokenExists(s, tokenId) + } + + #[callable(sig=b"setBaseURI(string)")] + public fun setBaseURI(newBaseURI: vector) acquires State { + let s = borrow_global_mut(self()); + s.baseURI = newBaseURI; + } + + #[callable(sig=b"baseURI() returns (string)"), view] + public fun baseURI(): vector acquires State { + let s = borrow_global_mut(self()); + s.baseURI + } + + #[event] + struct Transfer { + from: address, + to: address, + tokenId: U256, + } + + #[event] + struct Approval { + owner: address, + approved: address, + tokenId: U256, + } + + #[event] + struct ApprovalForAll { + owner: address, + operator: address, + approved: bool, + } + + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + name: vector, + symbol: vector, + owners: Table, + balances: Table, + tokenApprovals: Table, + operatorApprovals: Table>, + baseURI: vector, + currentTokenID: U256, + proxyRegistryAddress: address, + } + + #[create(sig=b"constructor(string,string,address,string)")] + /// Constructor of this contract. + public fun create(name: vector, symbol: vector, proxyRegistryAddress: address, baseURI: vector) acquires State { + // Initial state of contract + move_to( + &sign(self()), + State { + name, + symbol, + owners: Table::empty(), + balances: Table::empty(), + tokenApprovals: Table::empty(), + operatorApprovals: Table::empty>(), + baseURI, + currentTokenID: U256::zero(), + proxyRegistryAddress + } + ); + mintTo(sender()); // Minting with tokenId = 1. + mintTo(sender()); // Minting with tokenId = 2. + mintTo(sender()); // Minting with tokenId = 3. + } + + #[callable(sig=b"supportsInterface(bytes4) returns (bool)"), pure] + // Query if this contract implements a certain interface. + public fun supportsInterface(interfaceId: vector): bool { + interfaceId == IERC165_interfaceId() || + interfaceId == IERC721_interfaceId() || + interfaceId == IERC721Metadata_interfaceId() + } + + #[callable(sig=b"name() returns (string)"), view] + /// Get the name. + public fun name(): vector acquires State { + let s = borrow_global(self()); + *&s.name + } + + #[callable(sig=b"symbol() returns (string)"), view] + /// Get the symbol. + public fun symbol(): vector acquires State { + let s = borrow_global(self()); + *&s.symbol + } + + #[callable(sig=b"tokenURI(uint256) returns (string)"), view] + public fun tokenURI(tokenId: U256): vector acquires State { + require(exists_(tokenId), b"ERC721Metadata: URI query for nonexistent token"); + tokenURI_with_baseURI(baseURI(), tokenId) + } + + #[callable(sig=b"balanceOf(address) returns (uint256)"), view] + /// Count all NFTs assigned to an owner. + public fun balanceOf(owner: address): U256 acquires State { + require(owner != @0x0, b"ERC721: balance query for the zero address"); + let s = borrow_global_mut(self()); + *mut_balanceOf(s, owner) + } + + #[callable(sib=b"ownerOf(uint256) returns (address)"), view] + /// Find the owner of an NFT. + public fun ownerOf(tokenId: U256): address acquires State { + require(exists_(tokenId), b"ERC721: owner query for nonexistent token"); + let s = borrow_global_mut(self()); + *mut_ownerOf(s, tokenId) + } + + #[callable(sig=b"safeTransferFrom(address,address,uint256,bytes)")] // Overloading `safeTransferFrom` + /// Transfers the ownership of an NFT from one address to another address. + public fun safeTransferFrom_with_data(from: address, to: address, tokenId: U256, data: vector) acquires State { + transferFrom(from, to, tokenId); + doSafeTransferAcceptanceCheck(from, to, tokenId, data); + } + + #[callable(sig=b"safeTransferFrom(address,address,uint256)")] + /// Transfers the ownership of an NFT from one address to another address. + public fun safeTransferFrom(from: address, to: address, tokenId: U256) acquires State { + safeTransferFrom_with_data(from, to, tokenId, b""); + } + + #[callable] + /// Transfer ownership of an NFT. THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + public fun transferFrom(from: address, to: address, tokenId: U256) acquires State { + require(isApprovedOrOwner(sender(), tokenId), b"ERC721: transfer caller is not owner nor approved"); + + require(ownerOf(tokenId) == from, b"ERC721: transfer from incorrect owner"); + require(to != @0x0, b"ERC721: transfer to the zero address"); + + // Clear approvals from the previous owner + approve_(@0x0, tokenId); + + let s = borrow_global_mut(self()); + + let mut_balance_from = mut_balanceOf(s, from); + *mut_balance_from = U256::sub(*mut_balance_from, U256::one()); + + let mut_balance_to = mut_balanceOf(s, to); + *mut_balance_to = U256::add(*mut_balance_to, U256::one()); + + let mut_owner_token = mut_ownerOf(s, tokenId); + *mut_owner_token = to; + + emit(Transfer{from, to, tokenId}); + } + + #[callable] + /// Change or reaffirm the approved address for an NFT. + public fun approve(approved: address, tokenId: U256) acquires State { + let owner = ownerOf(tokenId); + require(approved != owner, b"ERC721: approval to current owner"); + require((sender() == owner) || isApprovedForAll(owner, sender()), b"ERC721: approve caller is not owner nor approved for all"); + approve_(approved, tokenId); + } + + fun approve_(approved: address, tokenId: U256) acquires State { + let s = borrow_global_mut(self()); + *mut_tokenApproval(s, tokenId) = approved; + emit(Approval{owner: ownerOf(tokenId), approved, tokenId}) + } + + #[callable] + /// Enable or disable approval for a third party ("operator") to manage + /// all of the sender's assets. + public fun setApprovalForAll(operator: address, approved: bool) acquires State { + setApprovalForAll_(sender(), operator, approved); + } + + fun setApprovalForAll_(owner: address, operator: address, approved: bool) acquires State { + require(owner != operator, b"ERC721: approve to caller"); + let s = borrow_global_mut(self()); + *mut_operatorApproval(s, owner, operator) = approved; + emit(ApprovalForAll{owner, operator, approved}) + } + + #[callable, view] + /// Get the approved address for a single NFT. + public fun getApproved(tokenId: U256): address acquires State { + let s = borrow_global_mut(self()); + require(tokenExists(s, tokenId), b"ERC721: approved query for nonexistent token"); + *mut_tokenApproval(s, tokenId) + } + + #[callable, view] + /// Query if an address is an authorized operator for another address. + public fun isApprovedForAll(owner: address, operator: address): bool acquires State { + let s = borrow_global_mut(self()); + *mut_operatorApproval(s, owner, operator) + } + + /// Helper function to return true iff `spender` is the owner or an approved one for `tokenId`. + fun isApprovedOrOwner(spender: address, tokenId: U256): bool acquires State { + let s = borrow_global_mut(self()); + require(tokenExists(s, tokenId), b"ERC721: operator query for nonexistent token"); + let owner = ownerOf(tokenId); + return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, owner: address): &mut U256 { + Table::borrow_mut_with_default(&mut s.balances, &owner, U256::zero()) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_ownerOf(s: &mut State, tokenId: U256): &mut address { + Table::borrow_mut_with_default(&mut s.owners, &tokenId, @0x0) + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_tokenApproval(s: &mut State, tokenId: U256): &mut address { + Table::borrow_mut_with_default(&mut s.tokenApprovals, &tokenId, @0x0) + } + + /// Helper function to return a mut ref to the operator approval. + fun mut_operatorApproval(s: &mut State, owner: address, operator: address): &mut bool { + if(!Table::contains(&s.operatorApprovals, &owner)) { + Table::insert( + &mut s.operatorApprovals, + &owner, + Table::empty() + ) + }; + let approvals = Table::borrow_mut(&mut s.operatorApprovals, &owner); + Table::borrow_mut_with_default(approvals, &operator, false) + } + + /// Helper function to return true iff the token exists. + fun tokenExists(s: &mut State, tokenId: U256): bool { + let mut_ownerOf_tokenId = mut_ownerOf(s, tokenId); + *mut_ownerOf_tokenId != @0x0 + } + + /// Helper function for the acceptance check. + fun doSafeTransferAcceptanceCheck(from: address, to: address, tokenId: U256, data: vector) { + if (isContract(to)) { + let result = IERC721Receiver_try_call_onERC721Received(to, sender(), from, tokenId, data); + if (ExternalResult::is_err_reason(&result)) { + // abort_with(b"err_reason"); + let reason = ExternalResult::unwrap_err_reason(result); + abort_with(reason); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"ERC721: transfer to non ERC721Receiver implementer"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else if (ExternalResult::is_ok(&result)) { + // abort_with(b"ok"); + let retval = ExternalResult::unwrap(result); + let expected = IERC721Receiver_selector_onERC721Received(); + require(retval == expected, b"ERC721: transfer to non ERC721Receiver implementer"); + } else { + abort_with(b"other"); + } + } + } + + #[external(sig=b"onERC721Received(address,address,uint256,bytes) returns (bytes4)")] + public native fun IERC721Receiver_try_call_onERC721Received(contract: address, operator: address, from: address, tokenId: U256, bytes: vector): ExternalResult>; +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable_Sol.sol b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable_Sol.sol new file mode 100644 index 000000000..f522b0673 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ERC721Tradable_Sol.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; + +/** + * @title ERC721Mock + * This mock just provides a public safeMint, mint, and burn functions for testing purposes + */ +contract ERC721Tradable_Sol is ERC721 { + string private baseURI_; + constructor(string memory name, string memory symbol, string memory newBaseURI) ERC721(name, symbol) { + baseURI_ = newBaseURI; + + _mint(msg.sender, 1); + _mint(msg.sender, 2); + _mint(msg.sender, 3); + } + + function _baseURI() internal override view returns (string memory) { + return baseURI_; + } + + function baseURI() public view returns (string memory) { + return _baseURI(); + } + + function exists(uint256 tokenId) public view returns (bool) { + return _exists(tokenId); + } + + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } + + function safeMint(address to, uint256 tokenId) public { + _safeMint(to, tokenId); + } + + function safeMint( + address to, + uint256 tokenId, + bytes memory _data + ) public { + _safeMint(to, tokenId, _data); + } + + function burn(uint256 tokenId) public { + _burn(tokenId); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Event.sol b/vendors/move/crates/evm/hardhat-examples/contracts/Event.sol new file mode 100644 index 000000000..837b6108c --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Event.sol @@ -0,0 +1,52 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +contract Event_Sol { + event SimpleEvent(uint64 x); + event U256Event(uint256 x); + event AddressEvent(address x); + event MyEvent(uint64 x, string message); + event Transfer(address indexed from, address indexed to, uint256 value); + + function emitNothing(uint64 x) public { + } + + function emitSimpleEvent(uint64 x) public { + emit SimpleEvent(x); + } + + function emitSimpleEventTwice(uint64 x) public { + emit SimpleEvent(x); + emit SimpleEvent(x+x); + } + + function emitMyEvent(uint64 x) public { + emit MyEvent(x, "hello_event"); + } + + function emitMyEventTwice(uint64 x) public { + emit MyEvent(x, "hello_event_#1"); + emit MyEvent(x+x, "hello_event_#2"); + } + + function emitMyEventWith(uint64 x, string memory message) public { + emit MyEvent(x, message); + } + + function emitMyEventWithTwice(uint64 x, string memory message) public { + emit MyEvent(x, message); + emit MyEvent(x+x, message); + } + + function emitTransfer(address from, address to, uint256 value) public { + emit Transfer(from, to, value); + } + + function emitU256Event(uint256 x) public { + emit U256Event(x); + } + + function emitAddressEvent(address a) public { + emit AddressEvent(a); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Event/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/Event/Move.toml new file mode 100644 index 000000000..c342d3ae7 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Event/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "Event" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Event/sources/Event.move b/vendors/move/crates/evm/hardhat-examples/contracts/Event/sources/Event.move new file mode 100644 index 000000000..3f7bfc9dc --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Event/sources/Event.move @@ -0,0 +1,85 @@ +#[evm_contract] +module 0x1::FortyTwo { + use Evm::Evm::{emit}; + use Evm::U256::U256; + + #[event] + struct SimpleEvent { + x: u64, + } + + #[callable(sig=b"emitNothing(uint64)")] + public fun emitNothing(_x: u64) { + } + + #[callable(sig=b"emitSimpleEvent(uint64)")] + public fun emitSimpleEvent(x: u64) { + emit(SimpleEvent{x}); + } + + #[callable(sig=b"emitSimpleEventTwice(uint64)")] + public fun emitSimpleEventTwice(x: u64) { + emit(SimpleEvent{x}); + emit(SimpleEvent{x: x+x}); + } + + #[event(sig=b"MyEvent(uint64,string)")] + struct MyEvent { + x: u64, + message: vector, + } + + #[callable(sig=b"emitMyEvent(uint64)")] + public fun emitMyEvent(x: u64) { + emit(MyEvent{x, message: b"hello_event"}); + } + + #[callable(sig=b"emitMyEventTwice(uint64)")] + public fun emitMyEventTwice(x: u64) { + emit(MyEvent{x, message: b"hello_event_#1"}); + emit(MyEvent{x: x+x, message: b"hello_event_#2"}); + } + + #[callable(sig=b"emitMyEventWith(uint64,string)")] + public fun emitMyEventWith(x: u64, message: vector) { + emit(MyEvent{x, message}); + } + + #[callable(sig=b"emitMyEventWithTwice(uint64,string)")] + public fun emitMyEventWithTwice(x: u64, message: vector) { + emit(MyEvent{x, message}); + emit(MyEvent{x: x+x, message}); + } + + #[event(sig=b"Transfer(address indexed,address indexed,uint256)")] + struct Transfer { + from: address, + to: address, + value: U256, + } + + #[callable(sig=b"emitTransfer(address,address,uint256)")] + public fun emitTransfer(from: address, to: address, value: U256) { + emit(Transfer{from, to, value}); + } + + #[event(sig=b"U256Event(uint256)")] + struct U256Event { + x: U256, + } + + #[callable(sig=b"emitU256Event(uint256)")] + public fun emitU256Event(x: U256) { + emit(U256Event{x}); + } + + #[event(sig=b"AddressEvent(address)")] + struct AddressEvent { + a: address, + } + + #[callable(sig=b"emitAddressEvent(address)")] + public fun emitAddressEvent(a: address) { + emit(AddressEvent{a}); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ExternalCall/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/ExternalCall/Move.toml new file mode 100644 index 000000000..53f95e038 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ExternalCall/Move.toml @@ -0,0 +1,11 @@ +[package] +name = "ExternalCall" +version = "0.0.0" + +[addresses] +std = "0x1" +Evm = "0x2" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } +MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/ExternalCall/sources/ExternalCall.move b/vendors/move/crates/evm/hardhat-examples/contracts/ExternalCall/sources/ExternalCall.move new file mode 100644 index 000000000..cb433ca94 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/ExternalCall/sources/ExternalCall.move @@ -0,0 +1,118 @@ +#[evm_contract] +module Evm::ExternalCall { + use Evm::ExternalResult::{Self, ExternalResult}; + use Evm::Evm::Unit; + use Evm::Evm::{abort_with, isContract, require, sender}; + use Evm::U256::{U256}; + use std::vector; + + #[external(sig=b"forty_two() returns (uint64)")] + public native fun external_call_forty_two(contract: address): u64; + + #[external(sig=b"forty_two() returns (uint64)")] + public native fun try_external_call_forty_two(contract: address): ExternalResult; + + #[external(sig=b"revertWithMessage()")] + public native fun external_call_revertWithMessage(contract: address); + + #[external(sig=b"revertWithMessage()")] + public native fun try_external_call_revertWithMessage(contract: address): ExternalResult; + + #[callable(sig=b"call_forty_two(address) returns (uint64)"), view] + public fun call_forty_two(contract: address): u64 { + external_call_forty_two(contract) + } + + #[callable(sig=b"call_revertWithMessage(address)"), pure] + public fun call_revertWithMessage(contract: address) { + external_call_revertWithMessage(contract); + } + + #[callable(sig=b"try_call_forty_two(address) returns (uint64)"), view] + public fun try_call_forty_two(contract: address): u64 { + let v = try_external_call_forty_two(contract); + if (ExternalResult::is_ok(&v)) { + return ExternalResult::unwrap(v) + } else if (ExternalResult::is_err_reason(&v)) { + abort_with(ExternalResult::unwrap_err_reason(v)); + return 0 + } else { + abort_with(b"not implemented"); + return 1 + } + } + + #[callable(sig=b"try_call_revertWithMessage(address)"), pure] + public fun try_call_revertWithMessage(contract: address) { + // TODO: try-call-catch. See `ExternalCall.sol`. + let v = try_external_call_revertWithMessage(contract); + if (ExternalResult::is_ok(&v)) { + } else if (ExternalResult::is_err_reason(&v)) { + abort_with(b"error reason"); + } else if (ExternalResult::is_err_data(&v)) { + abort_with(b"error data"); + } else if (ExternalResult::is_panic(&v)) { + abort_with(b"panic"); + } else { + abort_with(b"other"); + } + } + + #[callable] + public fun test_for_move_to_yul(from: address, to: address, tokenId: U256, data: vector) { + let _ = IERC721Receiver_try_call_onERC721Received(to, sender(), from, tokenId, data); + } + + #[callable(sig=b"doSafeTransferAcceptanceCheck(address,address,uint256,bytes)")] + public fun doSafeTransferAcceptanceCheck(from: address, to: address, tokenId: U256, data: vector) { + if (isContract(to)) { + let result = IERC721Receiver_try_call_onERC721Received(to, sender(), from, tokenId, data); + + if (ExternalResult::is_ok(&result)) { + abort_with(b"ok"); + } else if (ExternalResult::is_err_reason(&result)) { + let reason = ExternalResult::unwrap_err_reason(result); + abort_with(reason); + //abort_with(b"err_reason"); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"err_data"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else { + abort_with(b"other"); + } + } + } + + #[external(sig=b"onERC721Received(address,address,uint256,bytes) returns (bytes4)")] + public native fun IERC721Receiver_try_call_onERC721Received(contract: address, operator: address, from: address, tokenId: U256, bytes: vector): ExternalResult>; + + public fun IERC721Receiver_selector_onERC721Received(): vector { + x"150b7a02" + } + + #[callable(sig=b"doSafeBatchTransferAcceptanceCheck(address,address,address,uint256[],uint256[],bytes)")] + public fun doSafeBatchTransferAcceptanceCheck(operator: address, from: address, to: address, ids: vector, amounts: vector, data: vector) { + if (isContract(to)) { + let result = IERC1155Receiver_try_call_onERC1155BatchReceived(to, operator, from, ids, amounts, data); + if (ExternalResult::is_err_reason(&result)) { + abort_with(b"err_reason"); + } else if (ExternalResult::is_err_data(&result)) { + abort_with(b"err_data"); + } else if (ExternalResult::is_panic(&result)) { + abort_with(b"panic"); + } else if (ExternalResult::is_ok(&result)) { + abort_with(b"ok"); + } else { + abort_with(b"other"); + } + } + } + + #[external(sig=b"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes) returns (bytes4)")] + public native fun IERC1155Receiver_try_call_onERC1155BatchReceived(contract: address, operator: address, from: address, ids: vector, amounts: vector, bytes: vector): ExternalResult>; + + public fun IERC1155Receiver_selector_onERC1155BatchReceived(): vector { + x"bc197c81" + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo.sol b/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo.sol new file mode 100644 index 000000000..fe82d5804 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo.sol @@ -0,0 +1,20 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +contract FortyTwo_Sol { + function forty_two() public pure returns (uint64) { + return 42; + } + + function forty_two_as_u256() public pure returns (uint256) { + return 42; + } + + function forty_two_as_string() public pure returns (string memory) { + return "forty two"; + } + + function forty_two_plus_alpha(uint64 alpha) public pure returns (uint64) { + return 42 + alpha; + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo/Move.toml new file mode 100644 index 000000000..6ceee8f8c --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "FortyTwo" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo/sources/FortyTwo.move b/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo/sources/FortyTwo.move new file mode 100644 index 000000000..8bf7e639b --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/FortyTwo/sources/FortyTwo.move @@ -0,0 +1,25 @@ +#[evm_contract] +module 0x1::FortyTwo { + use Evm::U256::{u256_from_u128, U256}; + + #[callable, pure] + public fun forty_two(): u64 { + 42 + } + + #[callable, pure] + public fun forty_two_as_u256(): U256 { + u256_from_u128(42) + } + + // TODO: move-to-yul does not support literal string. + #[callable(sig=b"forty_two_as_string() returns (string)"), pure] + public fun forty_two_as_string(): vector { + b"forty two" + } + + #[callable, pure] + public fun forty_two_plus_alpha(alpha: u64): u64 { + 42 + alpha + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Greeter.sol b/vendors/move/crates/evm/hardhat-examples/contracts/Greeter.sol new file mode 100644 index 000000000..30d7d7f08 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Greeter.sol @@ -0,0 +1,22 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +import "hardhat/console.sol"; + +contract Greeter_Sol { + string private greeting; + + constructor(string memory _greeting) { + console.log("Deploying a Greeter with greeting:", _greeting); + greeting = _greeting; + } + + function greet() public view returns (string memory) { + return greeting; + } + + function setGreeting(string memory _greeting) public { + console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); + greeting = _greeting; + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Greeter/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/Greeter/Move.toml new file mode 100644 index 000000000..08403d0cb --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Greeter/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "Greeter" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Greeter/sources/Greeter.move b/vendors/move/crates/evm/hardhat-examples/contracts/Greeter/sources/Greeter.move new file mode 100644 index 000000000..99c5a11f3 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Greeter/sources/Greeter.move @@ -0,0 +1,29 @@ +#[evm_contract] +module Evm::Greeter { + use Evm::Evm::{self}; + use Evm::Evm::sign; + + struct State has key { + greeting: vector, + } + + #[create(sig=b"constructor(string)")] + public fun create(greeting: vector) { + move_to( + &sign(self()), + State { + greeting, + } + ); + } + + #[callable(sig=b"greet() returns (string)"), view] + public fun greet(): vector acquires State { + borrow_global(self()).greeting + } + + #[callable(sig=b"setGreeting(string)")] + public fun setGreeting(greeting: vector) acquires State { + borrow_global_mut(self()).greeting = greeting; + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Native.sol b/vendors/move/crates/evm/hardhat-examples/contracts/Native.sol new file mode 100644 index 000000000..4c8365bc5 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Native.sol @@ -0,0 +1,20 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/utils/Address.sol"; + +contract Native_Sol { + using Address for address; + + function getContractAddr() public view returns (address) { + return address(this); + } + + function getSenderAddr() public view returns (address) { + return msg.sender; + } + + function getIsContract(address addr) public view returns (bool) { + return addr.isContract(); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Native/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/Native/Move.toml new file mode 100644 index 000000000..b75025cf4 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Native/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "Native" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Native/sources/Native.move b/vendors/move/crates/evm/hardhat-examples/contracts/Native/sources/Native.move new file mode 100644 index 000000000..c2117dd3c --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Native/sources/Native.move @@ -0,0 +1,19 @@ +#[evm_contract] +module 0x1::Native { + use Evm::Evm::{self, sender, isContract}; + + #[callable, view] + public fun getContractAddr(): address { + self() + } + + #[callable, view] + public fun getSenderAddr(): address { + sender() + } + + #[callable, view] + public fun getIsContract(a: address): bool { + isContract(a) + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Revert.sol b/vendors/move/crates/evm/hardhat-examples/contracts/Revert.sol new file mode 100644 index 000000000..11e5f8ea4 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Revert.sol @@ -0,0 +1,15 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +contract Revert_Sol { + function revertIf0(uint64 x) public pure returns (uint64) { + if (x == 0) { + revert(); + } + return x; + } + + function revertWithMessage() public pure returns (uint64) { + revert('error message'); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Revert/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/Revert/Move.toml new file mode 100644 index 000000000..b71d5e0ba --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Revert/Move.toml @@ -0,0 +1,6 @@ +[package] +name = "Revert" +version = "0.0.0" + +[dependencies] +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Revert/sources/Revert.move b/vendors/move/crates/evm/hardhat-examples/contracts/Revert/sources/Revert.move new file mode 100644 index 000000000..d58015b4a --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Revert/sources/Revert.move @@ -0,0 +1,17 @@ +#[evm_contract] +module 0x1::Revert { + use Evm::U256::{u256_from_u128, U256}; + use Evm::Evm::abort_with; + + #[callable, pure] + public fun revertIf0(x: u64) { + if (x == 0) { + abort(0); + } + } + + #[callable, pure] + public fun revertWithMessage() { + abort_with(b"error message"); + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/StructABI_Sol.sol b/vendors/move/crates/evm/hardhat-examples/contracts/StructABI_Sol.sol new file mode 100644 index 000000000..1391ee769 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/StructABI_Sol.sol @@ -0,0 +1,32 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +contract StructABI_Sol { + + address private c; + + struct S { + uint64 a; + bool b; + S2 c; + } + + struct S2 { + uint64 x; + } + + constructor(address _c) { + c = _c; + } + + function call_s() public returns (bool) { + S memory s = S(42, true, S2(41)); + (bool b, ) = c.call(abi.encodeWithSignature("test((uint64,bool,(uint64)))", s)); + return b; + } + + function safeTransferFrom(S memory s) public returns (S2 memory) { + return s.c; + } + +} diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Token/Move.toml b/vendors/move/crates/evm/hardhat-examples/contracts/Token/Move.toml new file mode 100644 index 000000000..8d4fd4654 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Token/Move.toml @@ -0,0 +1,7 @@ +[package] +name = "Token" +version = "0.0.0" + +[dependencies] +MoveStdlib = { local = "../../../../move-stdlib" } +EvmStdlib = { local = "../../../stdlib" } diff --git a/vendors/move/crates/evm/hardhat-examples/contracts/Token/sources/Token.move b/vendors/move/crates/evm/hardhat-examples/contracts/Token/sources/Token.move new file mode 100644 index 000000000..2b772e34c --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/contracts/Token/sources/Token.move @@ -0,0 +1,75 @@ +#[evm_contract] +module Evm::Token { + use Evm::Evm::{self, sender, sign}; + use Evm::Table::{Self, Table}; + use Evm::U256::{Self, U256}; + use std::errors; + + /// Represents the state of this contract. This is located at `borrow_global(self())`. + struct State has key { + total_supply: U256, + balances: Table, + name: vector, + } + + #[create(sig=b"constructor(string)")] + public fun create(name: vector) acquires State { + move_to( + &sign(self()), + State { + total_supply: U256::zero(), + balances: Table::empty(), + name + } + ); + mint(sender(), U256::u256_from_u128(42)); + } + + #[callable(sig=b"name() returns (string)"), view] + /// Returns the name of the token + public fun name(): vector acquires State { + *&borrow_global(self()).name + } + + #[callable(sig=b"totalSupply() returns (uint256)"), view] + public fun totalSupply(): U256 acquires State { + *&borrow_global(self()).total_supply + } + + + #[callable(sig=b"balanceOf(address) returns (uint256)"), view] + public fun balanceOf(owner: address): U256 acquires State { + let s = borrow_global_mut(self()); + *mut_balanceOf(s, owner) + } + + #[callable(sig=b"mint(address, uint256)")] + public fun mint(account: address, amount: U256) acquires State { + let s = borrow_global_mut(self()); + s.total_supply = U256::add(s.total_supply, amount); + let mut_bal_account = mut_balanceOf(s, account); + *mut_bal_account = U256::add(*mut_bal_account, amount); + } + + #[callable(sig=b"transfer(address, uint256) returns (bool)")] + /// Transfers the amount from the sending account to the given account + public fun transfer(to: address, amount: U256): bool acquires State { + assert!(sender() != to, errors::invalid_argument(0)); + do_transfer(sender(), to, amount); + true + } + + fun do_transfer(from: address, to: address, amount: U256) acquires State { + let s = borrow_global_mut(self()); + let from_bal = mut_balanceOf(s, from); + assert!(U256::le(copy amount, *from_bal), errors::limit_exceeded(0)); + *from_bal = U256::sub(*from_bal, copy amount); + let to_bal = mut_balanceOf(s, to); + *to_bal = U256::add(*to_bal, copy amount); + } + + /// Helper function to return a mut ref to the balance of a owner. + fun mut_balanceOf(s: &mut State, owner: address): &mut U256 { + Table::borrow_mut_with_default(&mut s.balances, &owner, U256::zero()) + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/hardhat.config.js b/vendors/move/crates/evm/hardhat-examples/hardhat.config.js new file mode 100644 index 000000000..f1a8bd579 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/hardhat.config.js @@ -0,0 +1,52 @@ +require("@nomiclabs/hardhat-waffle"); +require("@nomiclabs/hardhat-truffle5"); +require("hardhat-gas-reporter"); +require("hardhat-move"); + +// This is a sample Hardhat task. To learn how to create your own go to +// https://hardhat.org/guides/create-task.html +task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { + const accounts = await hre.ethers.getSigners(); + + for (const account of accounts) { + console.log(account.address); + } +}); + + +// Go to https://www.alchemyapi.io, sign up, create +// a new App in its dashboard, and replace "KEY" with its key +const ALCHEMY_API_KEY_FOR_ROPSTEN = "KEY1"; +const ALCHEMY_API_KEY_FOR_RINKEBY = "KEY2"; + +// Replace this private key with your Ropsten account private key +// To export your private key from Metamask, open Metamask and +// go to Account Details > Export Private Key +// Be aware of NEVER putting real Ether into testing accounts +const PRIVATE_KEY = "0000000000000000000000000000000000000000000000000000000000000000"; + + +// You need to export an object to set up your config +// Go to https://hardhat.org/config/ to learn more + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: "0.8.4", + gasReporter: { + enabled: true + }, + networks: { + ropsten: { + url: `https://eth-ropsten.alchemyapi.io/v2/${ALCHEMY_API_KEY_FOR_ROPSTEN}`, + accounts: [`${PRIVATE_KEY}`] + }, + rinkeby: { + url: `https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_API_KEY_FOR_RINKEBY}`, + accounts: [`${PRIVATE_KEY}`], + // gas: 4250274, + // gasPrice: 2500000016 + } + } +}; diff --git a/vendors/move/crates/evm/hardhat-examples/package-lock.json b/vendors/move/crates/evm/hardhat-examples/package-lock.json new file mode 100644 index 000000000..c10b7f6cd --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/package-lock.json @@ -0,0 +1,24228 @@ +{ + "name": "hardhat-examples", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hardhat-examples", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@openzeppelin/contracts": "^4.5.0" + }, + "devDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.5", + "@nomiclabs/hardhat-truffle5": "^2.0.5", + "@nomiclabs/hardhat-waffle": "^2.0.3", + "@nomiclabs/hardhat-web3": "^2.0.0", + "@openzeppelin/test-helpers": "^0.5.15", + "chai": "^4.3.6", + "ethereum-waffle": "^3.4.4", + "ethers": "^5.6.2", + "hardhat": "^2.13.0", + "hardhat-gas-reporter": "^1.0.8", + "hardhat-move": "file:../hardhat-move", + "web3": "^1.7.1" + } + }, + "node_modules/@babel/runtime": { + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", + "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ensdomains/address-encoder": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz", + "integrity": "sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==", + "dev": true, + "dependencies": { + "bech32": "^1.1.3", + "blakejs": "^1.1.0", + "bn.js": "^4.11.8", + "bs58": "^4.0.1", + "crypto-addr-codec": "^0.1.7", + "nano-base32": "^1.0.1", + "ripemd160": "^2.0.2" + } + }, + "node_modules/@ensdomains/ens": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", + "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", + "deprecated": "Please use @ensdomains/ens-contracts", + "dev": true, + "dependencies": { + "bluebird": "^3.5.2", + "eth-ens-namehash": "^2.0.8", + "solc": "^0.4.20", + "testrpc": "0.0.1", + "web3-utils": "^1.0.0-beta.31" + } + }, + "node_modules/@ensdomains/ens/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/@ensdomains/ens/node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "node_modules/@ensdomains/ens/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@ensdomains/ens/node_modules/require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@ensdomains/ens/node_modules/solc": { + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", + "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", + "dev": true, + "dependencies": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + }, + "bin": { + "solcjs": "solcjs" + } + }, + "node_modules/@ensdomains/ens/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ensdomains/ens/node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "node_modules/@ensdomains/ens/node_modules/yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "dependencies": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "node_modules/@ensdomains/ens/node_modules/yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + }, + "node_modules/@ensdomains/ensjs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ensdomains/ensjs/-/ensjs-2.1.0.tgz", + "integrity": "sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.4.4", + "@ensdomains/address-encoder": "^0.1.7", + "@ensdomains/ens": "0.4.5", + "@ensdomains/resolver": "0.2.4", + "content-hash": "^2.5.2", + "eth-ens-namehash": "^2.0.8", + "ethers": "^5.0.13", + "js-sha3": "^0.8.0" + } + }, + "node_modules/@ensdomains/resolver": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", + "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", + "deprecated": "Please use @ensdomains/ens-contracts", + "dev": true + }, + "node_modules/@ethereum-waffle/chai": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", + "integrity": "sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==", + "dev": true, + "dependencies": { + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.5.2" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/compiler": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz", + "integrity": "sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==", + "dev": true, + "dependencies": { + "@resolver-engine/imports": "^0.3.3", + "@resolver-engine/imports-fs": "^0.3.3", + "@typechain/ethers-v5": "^2.0.0", + "@types/mkdirp": "^0.5.2", + "@types/node-fetch": "^2.5.5", + "ethers": "^5.0.1", + "mkdirp": "^0.5.1", + "node-fetch": "^2.6.1", + "solc": "^0.6.3", + "ts-generator": "^0.1.1", + "typechain": "^3.0.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/ens": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz", + "integrity": "sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==", + "dev": true, + "dependencies": { + "@ensdomains/ens": "^0.4.4", + "@ensdomains/resolver": "^0.2.4", + "ethers": "^5.5.2" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/mock-contract": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz", + "integrity": "sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.5.0", + "ethers": "^5.5.2" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereum-waffle/provider": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz", + "integrity": "sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==", + "dev": true, + "dependencies": { + "@ethereum-waffle/ens": "^3.4.4", + "ethers": "^5.5.2", + "ganache-core": "^2.13.2", + "patch-package": "^6.2.2", + "postinstall-postinstall": "^2.1.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@ethereumjs/common": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.3.tgz", + "integrity": "sha512-mQwPucDL7FDYIg9XQ8DL31CnIYZwGhU5hyOO5E+BMmT71G0+RHvIT5rIkLBirJEKxV6+Rcf9aEIY0kXInxUWpQ==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.4" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", + "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.6.3", + "ethereumjs-util": "^7.1.4" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.0.tgz", + "integrity": "sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", + "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", + "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", + "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", + "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", + "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", + "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", + "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", + "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.0.tgz", + "integrity": "sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.6.0", + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", + "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.0.tgz", + "integrity": "sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/basex": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/wordlists": "^5.6.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", + "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hdnode": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", + "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", + "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", + "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/sha2": "^5.6.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", + "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.2.tgz", + "integrity": "sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/basex": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/strings": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/random": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", + "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", + "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", + "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", + "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", + "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/sha2": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", + "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", + "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", + "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.0.tgz", + "integrity": "sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/hdnode": "^5.6.0", + "@ethersproject/json-wallets": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/wordlists": "^5.6.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", + "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", + "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/hash": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.0.tgz", + "integrity": "sha512-LczOjjxY4A7XYloxzyxJIHONELmUxVZncpOLoClpEcTiebiVdM46KRPYXGuULro9oNNR2xdVx3yoKiQjdfWmoA==", + "dev": true, + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@noble/hashes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz", + "integrity": "sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==", + "dev": true + }, + "node_modules/@noble/secp256k1": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.5.5.tgz", + "integrity": "sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nomicfoundation/ethereumjs-block": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.2.2.tgz", + "integrity": "sha512-atjpt4gc6ZGZUPHBAQaUJsm1l/VCo7FmyQ780tMGO8QStjLdhz09dXynmhwVTy5YbRr0FOh/uX3QaEM0yIB2Zg==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "3.1.2", + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "@nomicfoundation/ethereumjs-trie": "5.0.5", + "@nomicfoundation/ethereumjs-tx": "4.1.2", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.2.2.tgz", + "integrity": "sha512-6AIB2MoTEPZJLl6IRKcbd8mUmaBAQ/NMe3O7OsAOIiDjMNPPH5KaUQiLfbVlegT4wKIg/GOsFH7XlH2KDVoJNg==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "4.2.2", + "@nomicfoundation/ethereumjs-common": "3.1.2", + "@nomicfoundation/ethereumjs-ethash": "2.0.5", + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "@nomicfoundation/ethereumjs-trie": "5.0.5", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "abstract-level": "^1.0.3", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "level": "^8.0.0", + "lru-cache": "^5.1.1", + "memory-level": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.1.2.tgz", + "integrity": "sha512-JAEBpIua62dyObHM9KI2b4wHZcRQYYge9gxiygTWa3lNCr2zo+K0TbypDpgiNij5MCGNWP1eboNfNfx1a3vkvA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-util": "8.0.6", + "crc-32": "^1.2.0" + } + }, + "node_modules/@nomicfoundation/ethereumjs-ethash": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.5.tgz", + "integrity": "sha512-xlLdcICGgAYyYmnI3r1t0R5fKGBJNDQSOQxXNjVO99JmxJIdXR5MgPo5CSJO1RpyzKOgzi3uIFn8agv564dZEQ==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "4.2.2", + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "abstract-level": "^1.0.3", + "bigint-crypto-utils": "^3.0.23", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.3.2.tgz", + "integrity": "sha512-I00d4MwXuobyoqdPe/12dxUQxTYzX8OckSaWsMcWAfQhgVDvBx6ffPyP/w1aL0NW7MjyerySPcSVfDJAMHjilw==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "3.1.2", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.3.tgz", + "integrity": "sha512-DZMzB/lqPK78T6MluyXqtlRmOMcsZbTTbbEyAjo0ncaff2mqu/k8a79PBcyvpgAhWD/R59Fjq/x3ro5Lof0AtA==", + "dev": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.5.tgz", + "integrity": "sha512-CAhzpzTR5toh/qOJIZUUOnWekUXuRqkkzaGAQrVcF457VhtCmr+ddZjjK50KNZ524c1XP8cISguEVNqJ6ij1sA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "3.1.2", + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "@nomicfoundation/ethereumjs-trie": "5.0.5", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1" + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@nomicfoundation/ethereumjs-trie": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.5.tgz", + "integrity": "sha512-+8sNZrXkzvA1NH5F4kz5RSYl1I6iaRz7mAZRsyxOm0IVY4UaP43Ofvfp/TwOalFunurQrYB5pRO40+8FBcxFMA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "ethereum-cryptography": "0.1.3", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.1.2.tgz", + "integrity": "sha512-emJBJZpmTdUa09cqxQqHaysbBI9Od353ZazeH7WgPb35miMgNY6mb7/3vBA98N5lUW/rgkiItjX0KZfIzihSoQ==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "3.1.2", + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.6.tgz", + "integrity": "sha512-jOQfF44laa7xRfbfLXojdlcpkvxeHrE2Xu7tSeITsWFgoII163MzjOwFEzSNozHYieFysyoEMhCdP+NY5ikstw==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.4.2.tgz", + "integrity": "sha512-PRTyxZMP6kx+OdAzBhuH1LD2Yw+hrSpaytftvaK//thDy2OI07S0nrTdbrdk7b8ZVPAc9H9oTwFBl3/wJ3w15g==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "4.2.2", + "@nomicfoundation/ethereumjs-blockchain": "6.2.2", + "@nomicfoundation/ethereumjs-common": "3.1.2", + "@nomicfoundation/ethereumjs-evm": "1.3.2", + "@nomicfoundation/ethereumjs-rlp": "4.0.3", + "@nomicfoundation/ethereumjs-statemanager": "1.0.5", + "@nomicfoundation/ethereumjs-trie": "5.0.5", + "@nomicfoundation/ethereumjs-tx": "4.1.2", + "@nomicfoundation/ethereumjs-util": "8.0.6", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", + "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", + "dev": true, + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.1", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.1", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.1" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", + "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", + "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", + "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", + "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", + "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", + "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", + "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", + "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", + "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", + "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomiclabs/hardhat-ethers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.5.tgz", + "integrity": "sha512-A2gZAGB6kUvLx+kzM92HKuUF33F1FSe90L0TmkXkT2Hh0OKRpvWZURUSU2nghD2yC4DzfEZ3DftfeHGvZ2JTUw==", + "dev": true, + "peerDependencies": { + "ethers": "^5.0.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomiclabs/hardhat-truffle5": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.5.tgz", + "integrity": "sha512-taTWfieMP3Rvj+y90DgdNpviUJ4zxgjpW0V8D++uPkg5R7HXVWBTf43a1PYw+cBhcqN29P9gB1zSS1HC+uz1Mw==", + "dev": true, + "dependencies": { + "@nomiclabs/truffle-contract": "^4.2.23", + "@types/chai": "^4.2.0", + "chai": "^4.2.0", + "ethereumjs-util": "^7.1.3", + "fs-extra": "^7.0.1" + }, + "peerDependencies": { + "@nomiclabs/hardhat-web3": "^2.0.0", + "hardhat": "^2.6.4", + "web3": "^1.0.0-beta.36" + } + }, + "node_modules/@nomiclabs/hardhat-waffle": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz", + "integrity": "sha512-049PHSnI1CZq6+XTbrMbMv5NaL7cednTfPenx02k3cEh8wBMLa6ys++dBETJa6JjfwgA9nBhhHQ173LJv6k2Pg==", + "dev": true, + "dependencies": { + "@types/sinon-chai": "^3.2.3", + "@types/web3": "1.0.19" + }, + "peerDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", + "ethereum-waffle": "^3.2.0", + "ethers": "^5.0.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomiclabs/hardhat-web3": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz", + "integrity": "sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==", + "dev": true, + "dependencies": { + "@types/bignumber.js": "^5.0.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0", + "web3": "^1.0.0-beta.36" + } + }, + "node_modules/@nomiclabs/truffle-contract": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@nomiclabs/truffle-contract/-/truffle-contract-4.2.23.tgz", + "integrity": "sha512-Khj/Ts9r0LqEpGYhISbc+8WTOd6qJ4aFnDR+Ew+neqcjGnhwrIvuihNwPFWU6hDepW3Xod6Y+rTo90N8sLRDjw==", + "dev": true, + "dependencies": { + "@truffle/blockchain-utils": "^0.0.25", + "@truffle/contract-schema": "^3.2.5", + "@truffle/debug-utils": "^4.2.9", + "@truffle/error": "^0.0.11", + "@truffle/interface-adapter": "^0.4.16", + "bignumber.js": "^7.2.1", + "ethereum-ens": "^0.8.0", + "ethers": "^4.0.0-beta.1", + "source-map-support": "^0.5.19" + }, + "peerDependencies": { + "web3": "^1.2.1", + "web3-core-helpers": "^1.2.1", + "web3-core-promievent": "^1.2.1", + "web3-eth-abi": "^1.2.1", + "web3-utils": "^1.2.1" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@truffle/blockchain-utils": { + "version": "0.0.25", + "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.0.25.tgz", + "integrity": "sha512-XA5m0BfAWtysy5ChHyiAf1fXbJxJXphKk+eZ9Rb9Twi6fn3Jg4gnHNwYXJacYFEydqT5vr2s4Ou812JHlautpw==", + "dev": true, + "dependencies": { + "source-map-support": "^0.5.19" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@truffle/codec": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.7.1.tgz", + "integrity": "sha512-mNd6KnW6J0UB1zafGBXDlTEbCMvWpmPAJmzv7aF/nAIaN/F8UePSCiQ1OTQP39Rprj6GFiCCaWVnBAwum6UGSg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "bn.js": "^4.11.8", + "borc": "^2.1.2", + "debug": "^4.1.0", + "lodash.clonedeep": "^4.5.0", + "lodash.escaperegexp": "^4.1.2", + "lodash.partition": "^4.6.0", + "lodash.sum": "^4.0.2", + "semver": "^6.3.0", + "source-map-support": "^0.5.19", + "utf8": "^3.0.0", + "web3-utils": "1.2.9" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@truffle/debug-utils": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-4.2.14.tgz", + "integrity": "sha512-g5UTX2DPTzrjRjBJkviGI2IrQRTTSvqjmNWCNZNXP+vgQKNxL9maLZhQ6oA3BuuByVW/kusgYeXt8+W1zynC8g==", + "dev": true, + "dependencies": { + "@truffle/codec": "^0.7.1", + "@trufflesuite/chromafi": "^2.2.1", + "chalk": "^2.4.2", + "debug": "^4.1.0", + "highlight.js": "^9.15.8", + "highlightjs-solidity": "^1.0.18" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@truffle/error": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.11.tgz", + "integrity": "sha512-ju6TucjlJkfYMmdraYY/IBJaFb+Sa+huhYtOoyOJ+G29KcgytUVnDzKGwC7Kgk6IsxQMm62Mc1E0GZzFbGGipw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@truffle/interface-adapter": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.4.24.tgz", + "integrity": "sha512-2Zho4dJbm/XGwNleY7FdxcjXiAR3SzdGklgrAW4N/YVmltaJv6bT56ACIbPNN6AdzkTSTO65OlsB/63sfSa/VA==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.3", + "ethers": "^4.0.32", + "web3": "1.3.6" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@truffle/interface-adapter/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@trufflesuite/chromafi": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-2.2.2.tgz", + "integrity": "sha512-mItQwVBsb8qP/vaYHQ1kDt2vJLhjoEXJptT6y6fJGvFophMFhOI/NsTVUa0nJL1nyMeFiS6hSYuNVdpQZzB1gA==", + "dev": true, + "dependencies": { + "ansi-mark": "^1.0.0", + "ansi-regex": "^3.0.0", + "array-uniq": "^1.0.3", + "camelcase": "^4.1.0", + "chalk": "^2.3.2", + "cheerio": "^1.0.0-rc.2", + "detect-indent": "^5.0.0", + "he": "^1.1.1", + "highlight.js": "^10.4.1", + "lodash.merge": "^4.6.2", + "min-indent": "^1.0.0", + "strip-ansi": "^4.0.0", + "strip-indent": "^2.0.0", + "super-split": "^1.1.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@trufflesuite/chromafi/node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/@types/node": { + "version": "12.20.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", + "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/eth-lib": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", + "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/highlight.js": { + "version": "9.18.5", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz", + "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==", + "deprecated": "Support has ended for 9.x series. Upgrade to @latest", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": "*" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/highlightjs-solidity": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-1.2.2.tgz", + "integrity": "sha512-+cZ+1+nAO5Pi6c70TKuMcPmwqLECxiYhnQc1MxdXckK94zyWFMNZADzu98ECNlf5xCRdNh+XKp+eklmRU+Dniw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.3.6.tgz", + "integrity": "sha512-jEpPhnL6GDteifdVh7ulzlPrtVQeA30V9vnki9liYlUvLV82ZM7BNOQJiuzlDePuE+jZETZSP/0G/JlUVt6pOA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-bzz": "1.3.6", + "web3-core": "1.3.6", + "web3-eth": "1.3.6", + "web3-eth-personal": "1.3.6", + "web3-net": "1.3.6", + "web3-shh": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-bzz": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.3.6.tgz", + "integrity": "sha512-ibHdx1wkseujFejrtY7ZyC0QxQ4ATXjzcNUpaLrvM6AEae8prUiyT/OloG9FWDgFD2CPLwzKwfSQezYQlANNlw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40", + "underscore": "1.12.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-bzz/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.3.6.tgz", + "integrity": "sha512-gkLDM4T1Sc0T+HZIwxrNrwPg0IfWI0oABSglP2X5ZbBAYVUeEATA0o92LWV8BeF+okvKXLK1Fek/p6axwM/h3Q==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.3.6", + "web3-core-method": "1.3.6", + "web3-core-requestmanager": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-helpers": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.3.6.tgz", + "integrity": "sha512-nhtjA2ZbkppjlxTSwG0Ttu6FcPkVu1rCN5IFAOVpF/L0SEt+jy+O5l90+cjDq0jAYvlBwUwnbh2mR9hwDEJCNA==", + "dev": true, + "dependencies": { + "underscore": "1.12.1", + "web3-eth-iban": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-helpers/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-helpers/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-helpers/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-method": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.3.6.tgz", + "integrity": "sha512-RyegqVGxn0cyYW5yzAwkPlsSEynkdPiegd7RxgB4ak1eKk2Cv1q2x4C7D2sZjeeCEF+q6fOkVmo2OZNqS2iQxg==", + "dev": true, + "dependencies": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "underscore": "1.12.1", + "web3-core-helpers": "1.3.6", + "web3-core-promievent": "1.3.6", + "web3-core-subscriptions": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-method/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-method/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-method/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-promievent": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.3.6.tgz", + "integrity": "sha512-Z+QzfyYDTXD5wJmZO5wwnRO8bAAHEItT1XNSPVb4J1CToV/I/SbF7CuF8Uzh2jns0Cm1109o666H7StFFvzVKw==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-requestmanager": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.3.6.tgz", + "integrity": "sha512-2rIaeuqeo7QN1Eex7aXP0ZqeteJEPWXYFS/M3r3LXMiV8R4STQBKE+//dnHJXoo2ctzEB5cgd+7NaJM8S3gPyA==", + "dev": true, + "dependencies": { + "underscore": "1.12.1", + "util": "^0.12.0", + "web3-core-helpers": "1.3.6", + "web3-providers-http": "1.3.6", + "web3-providers-ipc": "1.3.6", + "web3-providers-ws": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-requestmanager/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-subscriptions": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.3.6.tgz", + "integrity": "sha512-wi9Z9X5X75OKvxAg42GGIf81ttbNR2TxzkAsp1g+nnp5K8mBwgZvXrIsDuj7Z7gx72Y45mWJADCWjk/2vqNu8g==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.12.1", + "web3-core-helpers": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core-subscriptions/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core/node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-core/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.3.6.tgz", + "integrity": "sha512-9+rnywRRpyX3C4hfsAQXPQh6vHh9XzQkgLxo3gyeXfbhbShUoq2gFVuy42vsRs//6JlsKdyZS7Z3hHPHz2wreA==", + "dev": true, + "dependencies": { + "underscore": "1.12.1", + "web3-core": "1.3.6", + "web3-core-helpers": "1.3.6", + "web3-core-method": "1.3.6", + "web3-core-subscriptions": "1.3.6", + "web3-eth-abi": "1.3.6", + "web3-eth-accounts": "1.3.6", + "web3-eth-contract": "1.3.6", + "web3-eth-ens": "1.3.6", + "web3-eth-iban": "1.3.6", + "web3-eth-personal": "1.3.6", + "web3-net": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-abi": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.3.6.tgz", + "integrity": "sha512-Or5cRnZu6WzgScpmbkvC6bfNxR26hqiKK4i8sMPFeTUABQcb/FU3pBj7huBLYbp9dH+P5W79D2MqwbWwjj9DoQ==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "underscore": "1.12.1", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-abi/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-abi/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-accounts": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.3.6.tgz", + "integrity": "sha512-Ilr0hG6ONbCdSlVKffasCmNwftD5HsNpwyQASevocIQwHdTlvlwO0tb3oGYuajbKOaDzNTwXfz25bttAEoFCGA==", + "dev": true, + "dependencies": { + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-common": "^1.3.2", + "ethereumjs-tx": "^2.1.1", + "scrypt-js": "^3.0.1", + "underscore": "1.12.1", + "uuid": "3.3.2", + "web3-core": "1.3.6", + "web3-core-helpers": "1.3.6", + "web3-core-method": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-accounts/node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-accounts/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-accounts/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-contract": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.3.6.tgz", + "integrity": "sha512-8gDaRrLF2HCg+YEZN1ov0zN35vmtPnGf3h1DxmJQK5Wm2lRMLomz9rsWsuvig3UJMHqZAQKD7tOl3ocJocQsmA==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "underscore": "1.12.1", + "web3-core": "1.3.6", + "web3-core-helpers": "1.3.6", + "web3-core-method": "1.3.6", + "web3-core-promievent": "1.3.6", + "web3-core-subscriptions": "1.3.6", + "web3-eth-abi": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-contract/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-contract/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-contract/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-ens": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.3.6.tgz", + "integrity": "sha512-n27HNj7lpSkRxTgSx+Zo7cmKAgyg2ElFilaFlUu/X2CNH23lXfcPm2bWssivH9z0ndhg0OyR4AYFZqPaqDHkJA==", + "dev": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "underscore": "1.12.1", + "web3-core": "1.3.6", + "web3-core-helpers": "1.3.6", + "web3-core-promievent": "1.3.6", + "web3-eth-abi": "1.3.6", + "web3-eth-contract": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-ens/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-ens/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-ens/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-iban": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.3.6.tgz", + "integrity": "sha512-nfMQaaLA/zsg5W4Oy/EJQbs8rSs1vBAX6b/35xzjYoutXlpHMQadujDx2RerTKhSHqFXSJeQAfE+2f6mdhYkRQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-iban/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-iban/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-personal": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.3.6.tgz", + "integrity": "sha512-pOHU0+/h1RFRYoh1ehYBehRbcKWP4OSzd4F7mDljhHngv6W8ewMHrAN8O1ol9uysN2MuCdRE19qkRg5eNgvzFQ==", + "dev": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.3.6", + "web3-core-helpers": "1.3.6", + "web3-core-method": "1.3.6", + "web3-net": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-personal/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-personal/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth-personal/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-eth/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-net": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.3.6.tgz", + "integrity": "sha512-KhzU3wMQY/YYjyMiQzbaLPt2kut88Ncx2iqjy3nw28vRux3gVX0WOCk9EL/KVJBiAA/fK7VklTXvgy9dZnnipw==", + "dev": true, + "dependencies": { + "web3-core": "1.3.6", + "web3-core-method": "1.3.6", + "web3-utils": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-net/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-net/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-net/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-providers-http": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.3.6.tgz", + "integrity": "sha512-OQkT32O1A06dISIdazpGLveZcOXhEo5cEX6QyiSQkiPk/cjzDrXMw4SKZOGQbbS1+0Vjizm1Hrp7O8Vp2D1M5Q==", + "dev": true, + "dependencies": { + "web3-core-helpers": "1.3.6", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-providers-ipc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.3.6.tgz", + "integrity": "sha512-+TVsSd2sSVvVgHG4s6FXwwYPPT91boKKcRuEFXqEfAbUC5t52XOgmyc2LNiD9LzPhed65FbV4LqICpeYGUvSwA==", + "dev": true, + "dependencies": { + "oboe": "2.1.5", + "underscore": "1.12.1", + "web3-core-helpers": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-providers-ipc/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-providers-ws": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.3.6.tgz", + "integrity": "sha512-bk7MnJf5or0Re2zKyhR3L3CjGululLCHXx4vlbc/drnaTARUVvi559OI5uLytc/1k5HKUUyENAxLvetz2G1dnQ==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.12.1", + "web3-core-helpers": "1.3.6", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-providers-ws/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-shh": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.3.6.tgz", + "integrity": "sha512-9zRo415O0iBslxBnmu9OzYjNErzLnzOsy+IOvSpIreLYbbAw0XkDWxv3SfcpKnTIWIACBR4AYMIxmmyi5iB3jw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-core": "1.3.6", + "web3-core-method": "1.3.6", + "web3-core-subscriptions": "1.3.6", + "web3-net": "1.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-utils": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.9.tgz", + "integrity": "sha512-9hcpuis3n/LxFzEVjwnVgvJzTirS2S9/MiNAa7l4WOEoywY+BSNwnRX4MuHnjkh9NY25B6QOjuNG6FNnSjTw1w==", + "dev": true, + "dependencies": { + "bn.js": "4.11.8", + "eth-lib": "0.2.7", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3-utils/node_modules/bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/@nomiclabs/truffle-contract/node_modules/web3/node_modules/web3-utils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", + "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.12.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@openzeppelin/contract-loader": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contract-loader/-/contract-loader-0.6.3.tgz", + "integrity": "sha512-cOFIjBjwbGgZhDZsitNgJl0Ye1rd5yu/Yx5LMgeq3u0ZYzldm4uObzHDFq4gjDdoypvyORjjJa3BlFA7eAnVIg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@openzeppelin/contract-loader/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/contract-loader/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@openzeppelin/contract-loader/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/contract-loader/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@openzeppelin/contract-loader/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/contract-loader/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@openzeppelin/contract-loader/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz", + "integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==" + }, + "node_modules/@openzeppelin/test-helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@openzeppelin/test-helpers/-/test-helpers-0.5.15.tgz", + "integrity": "sha512-10fS0kyOjc/UObo9iEWPNbC6MCeiQ7z97LDOJBj68g+AAs5pIGEI2h3V6G9TYTIq8VxOdwMQbfjKrx7Y3YZJtA==", + "dev": true, + "dependencies": { + "@openzeppelin/contract-loader": "^0.6.2", + "@truffle/contract": "^4.0.35", + "ansi-colors": "^3.2.3", + "chai": "^4.2.0", + "chai-bn": "^0.2.1", + "ethjs-abi": "^0.2.1", + "lodash.flatten": "^4.4.0", + "semver": "^5.6.0", + "web3": "^1.2.5", + "web3-utils": "^1.2.5" + } + }, + "node_modules/@openzeppelin/test-helpers/node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@openzeppelin/test-helpers/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@resolver-engine/core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", + "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "is-url": "^1.2.4", + "request": "^2.85.0" + } + }, + "node_modules/@resolver-engine/fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", + "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", + "dev": true, + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@resolver-engine/imports": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", + "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", + "dev": true, + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0", + "hosted-git-info": "^2.6.0", + "path-browserify": "^1.0.0", + "url": "^0.11.0" + } + }, + "node_modules/@resolver-engine/imports-fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", + "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", + "dev": true, + "dependencies": { + "@resolver-engine/fs": "^0.3.3", + "@resolver-engine/imports": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@scure/base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.0.0.tgz", + "integrity": "sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip32": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.0.1.tgz", + "integrity": "sha512-AU88KKTpQ+YpTLoicZ/qhFhRRIo96/tlb+8YmDDHR9yiKVjSsFZiefJO4wjS2PMTkz5/oIcw84uAq/8pleQURA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.0.0", + "@noble/secp256k1": "~1.5.2", + "@scure/base": "~1.0.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.0.0.tgz", + "integrity": "sha512-HrtcikLbd58PWOkl02k9V6nXWQyoa7A0+Ek9VF7z17DDk9XZAFUcIdqfh0jJXLypmizc5/8P6OxoUeKliiWv4w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.0.0", + "@scure/base": "~1.0.0" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dev": true, + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz", + "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==", + "dev": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@truffle/abi-utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.10.tgz", + "integrity": "sha512-zG3PSXwq4mrXOOBKzgmOqNlVe2ZBUNAFv0xHAq5DwWew8PSQ/+a0ixPbWXXc3xYbApJMlIXRM716fB5MiZ22FA==", + "dev": true, + "dependencies": { + "change-case": "3.0.2", + "faker": "^5.3.1", + "fast-check": "^2.12.1" + } + }, + "node_modules/@truffle/blockchain-utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.1.1.tgz", + "integrity": "sha512-o7nBlaMuasuADCCL2WzhvOXA5GT5ewd/F35cY6ZU69U5OUASR3ZP4CZetVCc5MZePPa/3CL9pzJ4Rhtg1ChwVA==", + "dev": true + }, + "node_modules/@truffle/codec": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.12.4.tgz", + "integrity": "sha512-8XCKMAP22fEVa8xGFA9lqBr5kWhyYW/41ekP0yFEXQhCSPEcZamc6I9h2KQGBrChdxGsKd82Y4138rHGKiQtjQ==", + "dev": true, + "dependencies": { + "@truffle/abi-utils": "^0.2.10", + "@truffle/compile-common": "^0.7.29", + "big.js": "^6.0.3", + "bn.js": "^5.1.3", + "cbor": "^5.1.0", + "debug": "^4.3.1", + "lodash": "^4.17.21", + "semver": "^7.3.4", + "utf8": "^3.0.0", + "web3-utils": "1.5.3" + } + }, + "node_modules/@truffle/codec/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/@truffle/codec/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@truffle/codec/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@truffle/codec/node_modules/eth-lib/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/@truffle/codec/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@truffle/codec/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@truffle/codec/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@truffle/codec/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/codec/node_modules/web3-utils/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/@truffle/codec/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@truffle/compile-common": { + "version": "0.7.29", + "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.29.tgz", + "integrity": "sha512-Z5h0jQh/GXsjnTBt02boV2QiQ1QlGlWlupZWsIcLHpBxQaw/TXTa7EvicPLWf7JQ3my56iaY3N5rkrQLAlFf1Q==", + "dev": true, + "dependencies": { + "@truffle/error": "^0.1.0", + "colors": "1.4.0" + } + }, + "node_modules/@truffle/contract": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.5.2.tgz", + "integrity": "sha512-2QWs2uC5HQZxTvto2XkHyK6uzLAEH5Zyza5itMPW3Lc6IdbsjWTVaA/YCS+YJSFI3vplkR8NkJjXWG9//jxn8g==", + "dev": true, + "dependencies": { + "@ensdomains/ensjs": "^2.0.1", + "@truffle/blockchain-utils": "^0.1.1", + "@truffle/contract-schema": "^3.4.6", + "@truffle/debug-utils": "^6.0.14", + "@truffle/error": "^0.1.0", + "@truffle/interface-adapter": "^0.5.12", + "bignumber.js": "^7.2.1", + "debug": "^4.3.1", + "ethers": "^4.0.32", + "web3": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" + } + }, + "node_modules/@truffle/contract-schema": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.6.tgz", + "integrity": "sha512-YzVAoPxEnM7pz7vLrQvtgtnpIwERrZcbYRjRTEJP8Y7rxudYDYaZ8PwjHD3j0SQxE6Y0WquDi3PtbfgZB9BwYQ==", + "dev": true, + "dependencies": { + "ajv": "^6.10.0", + "debug": "^4.3.1" + } + }, + "node_modules/@truffle/contract-schema/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@truffle/contract-schema/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@truffle/contract/node_modules/@types/node": { + "version": "12.20.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", + "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@truffle/contract/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@truffle/contract/node_modules/ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/@truffle/contract/node_modules/hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/web3": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", + "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-bzz": "1.5.3", + "web3-core": "1.5.3", + "web3-eth": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-shh": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-bzz": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", + "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-core": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", + "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-requestmanager": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-core-method": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", + "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.4.0", + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-core-requestmanager": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", + "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", + "dev": true, + "dependencies": { + "util": "^0.12.0", + "web3-core-helpers": "1.5.3", + "web3-providers-http": "1.5.3", + "web3-providers-ipc": "1.5.3", + "web3-providers-ws": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-core-subscriptions": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", + "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-core/node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/@truffle/contract/node_modules/web3-eth": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", + "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", + "dev": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-accounts": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-eth-ens": "1.5.3", + "web3-eth-iban": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-eth-accounts": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", + "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.3.0", + "@ethereumjs/tx": "^3.2.1", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-eth-accounts/node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/@truffle/contract/node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@truffle/contract/node_modules/web3-eth-contract": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", + "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-eth-ens": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", + "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", + "dev": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-eth-personal": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", + "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", + "dev": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-net": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", + "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", + "dev": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-providers-http": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", + "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", + "dev": true, + "dependencies": { + "web3-core-helpers": "1.5.3", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-providers-ipc": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", + "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", + "dev": true, + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-providers-ws": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", + "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-shh": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", + "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-net": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/contract/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/debug-utils": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.14.tgz", + "integrity": "sha512-LhtoKI86QzLFbb0dOQojNR1jl8Le0GL/fkhkaK/thdxMtkt5F7BVoO0f0CbnC9+vfp7qbgEcRct1suw38sVVGQ==", + "dev": true, + "dependencies": { + "@truffle/codec": "^0.12.4", + "@trufflesuite/chromafi": "^3.0.0", + "bn.js": "^5.1.3", + "chalk": "^2.4.2", + "debug": "^4.3.1", + "highlightjs-solidity": "^2.0.5" + } + }, + "node_modules/@truffle/debug-utils/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/@truffle/debug-utils/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@truffle/debug-utils/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@truffle/error": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.0.tgz", + "integrity": "sha512-RbUfp5VreNhsa2Q4YbBjz18rOQI909pG32bghl1hulO7IpvcqTS+C3Ge5cNbiWQ1WGzy1wIeKLW0tmQtHFB7qg==", + "dev": true + }, + "node_modules/@truffle/interface-adapter": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.12.tgz", + "integrity": "sha512-Qrc5VARnvSILYqZNsAM0xsUHqGqphLXVdIvDnhUA1Xj1xyNz8iboTr8bXorMd+Uspw+PXmsW44BJ/Wioo/jL2A==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.3", + "ethers": "^4.0.32", + "web3": "1.5.3" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/@types/node": { + "version": "12.20.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", + "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/eth-lib/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/ethers/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/web3": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", + "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-bzz": "1.5.3", + "web3-core": "1.5.3", + "web3-eth": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-shh": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-bzz": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", + "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-core": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", + "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-requestmanager": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-core-method": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", + "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.4.0", + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-core-requestmanager": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", + "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", + "dev": true, + "dependencies": { + "util": "^0.12.0", + "web3-core-helpers": "1.5.3", + "web3-providers-http": "1.5.3", + "web3-providers-ipc": "1.5.3", + "web3-providers-ws": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-core-subscriptions": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", + "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-eth": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", + "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", + "dev": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-accounts": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-eth-ens": "1.5.3", + "web3-eth-iban": "1.5.3", + "web3-eth-personal": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-eth-accounts": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", + "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.3.0", + "@ethereumjs/tx": "^3.2.1", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-eth-accounts/node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-eth-contract": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", + "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-eth-ens": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", + "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", + "dev": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-eth-contract": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-eth-personal": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", + "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", + "dev": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-method": "1.5.3", + "web3-net": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-net": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", + "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", + "dev": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-providers-http": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", + "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", + "dev": true, + "dependencies": { + "web3-core-helpers": "1.5.3", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-providers-ipc": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", + "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", + "dev": true, + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-providers-ws": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", + "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.5.3", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-shh": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", + "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-core": "1.5.3", + "web3-core-method": "1.5.3", + "web3-core-subscriptions": "1.5.3", + "web3-net": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@truffle/interface-adapter/node_modules/web3-utils/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/@trufflesuite/chromafi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz", + "integrity": "sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0", + "chalk": "^2.3.2", + "cheerio": "^1.0.0-rc.2", + "detect-indent": "^5.0.0", + "highlight.js": "^10.4.1", + "lodash.merge": "^4.6.2", + "strip-ansi": "^4.0.0", + "strip-indent": "^2.0.0" + } + }, + "node_modules/@trufflesuite/chromafi/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@trufflesuite/chromafi/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@trufflesuite/chromafi/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@typechain/ethers-v5": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", + "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", + "dev": true, + "dependencies": { + "ethers": "^5.0.2" + }, + "peerDependencies": { + "ethers": "^5.0.0", + "typechain": "^3.0.0" + } + }, + "node_modules/@types/async-eventemitter": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", + "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", + "dev": true + }, + "node_modules/@types/bignumber.js": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz", + "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==", + "deprecated": "This is a stub types definition for bignumber.js (https://github.com/MikeMcl/bignumber.js/). bignumber.js provides its own type definitions, so you don't need @types/bignumber.js installed!", + "dev": true, + "dependencies": { + "bignumber.js": "*" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "dev": true + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "dev": true + }, + "node_modules/@types/mkdirp": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", + "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "dev": true + }, + "node_modules/@types/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", + "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/sinon": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz", + "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinon-chai": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.8.tgz", + "integrity": "sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, + "node_modules/@types/underscore": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", + "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", + "dev": true + }, + "node_modules/@types/web3": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz", + "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==", + "dev": true, + "dependencies": { + "@types/bn.js": "*", + "@types/underscore": "*" + } + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-level": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", + "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/abstract-level/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true, + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", + "dev": true + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-mark": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ansi-mark/-/ansi-mark-1.0.4.tgz", + "integrity": "sha1-HNS6jVfxXxCdaq9uycqXhsik7mw=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0", + "array-uniq": "^1.0.3", + "chalk": "^2.3.2", + "strip-ansi": "^4.0.0", + "super-split": "^1.1.0" + } + }, + "node_modules/ansi-mark/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-mark/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "dependencies": { + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "dev": true, + "dependencies": { + "async": "^2.4.0" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true + }, + "node_modules/big-integer": { + "version": "1.6.36", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", + "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.1.1.tgz", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "node_modules/bigint-crypto-utils": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz", + "integrity": "sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw==", + "dev": true, + "dependencies": { + "bigint-mod-arith": "^3.1.0" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/bigint-mod-arith": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz", + "integrity": "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==", + "dev": true, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/body-parser/node_modules/raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/borc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", + "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "dev": true, + "dependencies": { + "bignumber.js": "^9.0.0", + "buffer": "^5.5.0", + "commander": "^2.15.0", + "ieee754": "^1.1.13", + "iso-url": "~0.4.7", + "json-text-sequence": "~0.1.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/borc/node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/borc/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "node_modules/browser-level": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", + "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "dev": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-aes/node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "dev": true, + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", + "dev": true + }, + "node_modules/bufferutil": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cbor": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", + "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", + "dev": true, + "dependencies": { + "bignumber.js": "^9.0.1", + "nofilter": "^1.0.4" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/cbor/node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-bn": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.2.tgz", + "integrity": "sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==", + "dev": true, + "peerDependencies": { + "bn.js": "^4.11.0", + "chai": "^4.0.0" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/change-case": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.0.2.tgz", + "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", + "dev": true, + "dependencies": { + "camel-case": "^3.0.0", + "constant-case": "^2.0.0", + "dot-case": "^2.1.0", + "header-case": "^1.0.0", + "is-lower-case": "^1.1.0", + "is-upper-case": "^1.1.0", + "lower-case": "^1.1.1", + "lower-case-first": "^1.0.0", + "no-case": "^2.3.2", + "param-case": "^2.1.0", + "pascal-case": "^2.0.0", + "path-case": "^2.1.0", + "sentence-case": "^2.1.0", + "snake-case": "^2.1.0", + "swap-case": "^1.1.0", + "title-case": "^2.1.0", + "upper-case": "^1.1.1", + "upper-case-first": "^1.1.0" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dev": true, + "dependencies": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", + "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", + "dev": true, + "dependencies": { + "css-select": "^4.3.0", + "css-what": "^6.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.3.1", + "domutils": "^2.8.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true + }, + "node_modules/classic-level": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", + "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "node_modules/command-line-args": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", + "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", + "dev": true, + "dependencies": { + "array-back": "^2.0.0", + "find-replace": "^1.0.3", + "typical": "^2.6.1" + }, + "bin": { + "command-line-args": "bin/cli.js" + } + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/constant-case": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", + "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", + "dev": true, + "dependencies": { + "snake-case": "^2.1.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/crc-32": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz", + "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==", + "dev": true, + "dependencies": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.3.1" + }, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-addr-codec": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz", + "integrity": "sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==", + "dev": true, + "dependencies": { + "base-x": "^3.0.8", + "big-integer": "1.6.36", + "blakejs": "^1.1.0", + "bs58": "^4.0.1", + "ripemd160-min": "0.0.6", + "safe-buffer": "^5.2.0", + "sha3": "^2.1.1" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.0.1.tgz", + "integrity": "sha512-z93ZGFLNc6yaoXAmVhqoSIb+BduplteCt1fepvwhBUQK6MNE4g6fgjpuZKJKp0esUe+vXWlIkwZZjNWoOKw0ZA==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs=", + "dev": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", + "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", + "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.59", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.59.tgz", + "integrity": "sha512-cOgyhW0tIJyQY1Kfw6Kr0viu9ZlUctVchRMZ7R0HiH3dxTSp5zJDLecwxUqPUrGKMsgBI1wd1FL+d9Jxfi4cLw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "dev": true, + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/eth-ens-namehash/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", + "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.0.0-beta.146", + "@solidity-parser/parser": "^0.14.0", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^4.0.40", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^7.1.1", + "req-cwd": "^2.0.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/eth-gas-reporter/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.0.3.tgz", + "integrity": "sha512-NQLTW0x0CosoVb/n79x/TRHtfvS3hgNUPTUSCu0vM+9k6IIhHFFrAOJReneexjZsoZxMjJHnJn4lrE8EbnSyqQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.0.0", + "@noble/secp256k1": "1.5.5", + "@scure/bip32": "1.0.1", + "@scure/bip39": "1.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "4.0.49", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", + "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "dev": true, + "dependencies": { + "aes-js": "3.0.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.3", + "js-sha3": "0.5.7", + "scrypt-js": "2.0.4", + "setimmediate": "1.0.4", + "uuid": "2.0.1", + "xmlhttprequest": "1.8.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/eth-gas-reporter/node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eth-gas-reporter/node_modules/hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eth-gas-reporter/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eth-gas-reporter/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eth-gas-reporter/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/eth-gas-reporter/node_modules/mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "dev": true, + "dependencies": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/eth-gas-reporter/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eth-gas-reporter/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eth-gas-reporter/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eth-gas-reporter/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/eth-gas-reporter/node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-gas-reporter/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/eth-gas-reporter/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/eth-gas-reporter/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "dependencies": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/eth-lib/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/eth-lib/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dev": true, + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereum-ens": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/ethereum-ens/-/ethereum-ens-0.8.0.tgz", + "integrity": "sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==", + "dev": true, + "dependencies": { + "bluebird": "^3.4.7", + "eth-ens-namehash": "^2.0.0", + "js-sha3": "^0.5.7", + "pako": "^1.0.4", + "underscore": "^1.8.3", + "web3": "^1.0.0-beta.34" + } + }, + "node_modules/ethereum-ens/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true + }, + "node_modules/ethereum-waffle": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", + "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", + "dev": true, + "dependencies": { + "@ethereum-waffle/chai": "^3.4.4", + "@ethereum-waffle/compiler": "^3.4.4", + "@ethereum-waffle/mock-contract": "^3.4.4", + "@ethereum-waffle/provider": "^3.4.4", + "ethers": "^5.0.1" + }, + "bin": { + "waffle": "bin/waffle" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-common": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz", + "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==", + "deprecated": "New package name format for new versions: @ethereumjs/common. Please update.", + "dev": true + }, + "node_modules/ethereumjs-tx": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", + "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-tx/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-tx/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", + "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "dev": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/ethers": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.2.tgz", + "integrity": "sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.6.0", + "@ethersproject/abstract-provider": "5.6.0", + "@ethersproject/abstract-signer": "5.6.0", + "@ethersproject/address": "5.6.0", + "@ethersproject/base64": "5.6.0", + "@ethersproject/basex": "5.6.0", + "@ethersproject/bignumber": "5.6.0", + "@ethersproject/bytes": "5.6.1", + "@ethersproject/constants": "5.6.0", + "@ethersproject/contracts": "5.6.0", + "@ethersproject/hash": "5.6.0", + "@ethersproject/hdnode": "5.6.0", + "@ethersproject/json-wallets": "5.6.0", + "@ethersproject/keccak256": "5.6.0", + "@ethersproject/logger": "5.6.0", + "@ethersproject/networks": "5.6.1", + "@ethersproject/pbkdf2": "5.6.0", + "@ethersproject/properties": "5.6.0", + "@ethersproject/providers": "5.6.2", + "@ethersproject/random": "5.6.0", + "@ethersproject/rlp": "5.6.0", + "@ethersproject/sha2": "5.6.0", + "@ethersproject/signing-key": "5.6.0", + "@ethersproject/solidity": "5.6.0", + "@ethersproject/strings": "5.6.0", + "@ethersproject/transactions": "5.6.0", + "@ethersproject/units": "5.6.0", + "@ethersproject/wallet": "5.6.0", + "@ethersproject/web": "5.6.0", + "@ethersproject/wordlists": "5.6.0" + } + }, + "node_modules/ethjs-abi": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", + "integrity": "sha1-4KepOn6BFjqUR3utVu3lJKtt5TM=", + "dev": true, + "dependencies": { + "bn.js": "4.11.6", + "js-sha3": "0.5.5", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-abi/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "node_modules/ethjs-abi/node_modules/js-sha3": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", + "integrity": "sha1-uvDA6MVK1ZA0R9+Wreekobynmko=", + "dev": true + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "dev": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dev": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/express/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dev": true, + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", + "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==", + "dev": true + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", + "dev": true + }, + "node_modules/fast-check": { + "version": "2.23.2", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.23.2.tgz", + "integrity": "sha512-ECYuSlp6NLpvOj8eScKsqoz1ihtCpSDuEC2ofdGvgsEu1obHYEGqreJ/iPzkJFy73yoU0kCFea7PHUQDNM0VNg==", + "dev": true, + "dependencies": { + "pure-rand": "^5.0.1" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/find-replace": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", + "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", + "dev": true, + "dependencies": { + "array-back": "^1.0.4", + "test-value": "^2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-replace/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/ganache-core": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", + "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", + "bundleDependencies": [ + "keccak" + ], + "deprecated": "ganache-core is now ganache; visit https://trfl.io/g7 for details", + "dev": true, + "hasShrinkwrap": true, + "dependencies": { + "abstract-leveldown": "3.0.0", + "async": "2.6.2", + "bip39": "2.5.0", + "cachedown": "1.0.0", + "clone": "2.1.2", + "debug": "3.2.6", + "encoding-down": "5.0.4", + "eth-sig-util": "3.0.0", + "ethereumjs-abi": "0.6.8", + "ethereumjs-account": "3.0.0", + "ethereumjs-block": "2.2.2", + "ethereumjs-common": "1.5.0", + "ethereumjs-tx": "2.1.2", + "ethereumjs-util": "6.2.1", + "ethereumjs-vm": "4.2.0", + "heap": "0.2.6", + "keccak": "3.0.1", + "level-sublevel": "6.6.4", + "levelup": "3.1.1", + "lodash": "4.17.20", + "lru-cache": "5.1.1", + "merkle-patricia-tree": "3.0.0", + "patch-package": "6.2.2", + "seedrandom": "3.0.1", + "source-map-support": "0.5.12", + "tmp": "0.1.0", + "web3-provider-engine": "14.2.1", + "websocket": "1.0.32" + }, + "engines": { + "node": ">=8.9.0" + }, + "optionalDependencies": { + "ethereumjs-wallet": "0.6.5", + "web3": "1.2.11" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abi": { + "version": "5.0.0-beta.153", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz", + "integrity": "sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==", + "dev": true, + "optional": true, + "dependencies": { + "@ethersproject/address": ">=5.0.0-beta.128", + "@ethersproject/bignumber": ">=5.0.0-beta.130", + "@ethersproject/bytes": ">=5.0.0-beta.129", + "@ethersproject/constants": ">=5.0.0-beta.128", + "@ethersproject/hash": ">=5.0.0-beta.128", + "@ethersproject/keccak256": ">=5.0.0-beta.127", + "@ethersproject/logger": ">=5.0.0-beta.129", + "@ethersproject/properties": ">=5.0.0-beta.131", + "@ethersproject/strings": ">=5.0.0-beta.130" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.8.tgz", + "integrity": "sha512-fqJXkewcGdi8LogKMgRyzc/Ls2js07yor7+g9KfPs09uPOcQLg7cc34JN+lk34HH9gg2HU0DIA5797ZR8znkfw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/networks": "^5.0.7", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/transactions": "^5.0.9", + "@ethersproject/web": "^5.0.12" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.10.tgz", + "integrity": "sha512-irx7kH7FDAeW7QChDPW19WsxqeB1d3XLyOLSXm0bfPqL1SS07LXWltBJUBUxqC03ORpAOcM3JQj57DU8JnVY2g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.0.8", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/address": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.0.9.tgz", + "integrity": "sha512-gKkmbZDMyGbVjr8nA5P0md1GgESqSGH7ILIrDidPdNXBl4adqbuA3OAuZx/O2oGpL6PtJ9BDa0kHheZ1ToHU3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/rlp": "^5.0.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/base64": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.7.tgz", + "integrity": "sha512-S5oh5DVfCo06xwJXT8fQC68mvJfgScTl2AXvbYMsHNfIBTDb084Wx4iA9MNlEReOv6HulkS+gyrUM/j3514rSw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/bignumber": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.13.tgz", + "integrity": "sha512-b89bX5li6aK492yuPP5mPgRVgIxxBP7ksaBtKX5QQBsrZTpNOjf/MR4CjcUrAw8g+RQuD6kap9lPjFgY4U1/5A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "bn.js": "^4.4.0" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/bytes": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.9.tgz", + "integrity": "sha512-k+17ZViDtAugC0s7HM6rdsTWEdIYII4RPCDkPEuxKc6i40Bs+m6tjRAtCECX06wKZnrEoR9pjOJRXHJ/VLoOcA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/constants": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.8.tgz", + "integrity": "sha512-sCc73pFBsl59eDfoQR5OCEZCRv5b0iywadunti6MQIr5lt3XpwxK1Iuzd8XSFO02N9jUifvuZRrt0cY0+NBgTg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.0.13" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/hash": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.10.tgz", + "integrity": "sha512-Tf0bvs6YFhw28LuHnhlDWyr0xfcDxSXdwM4TcskeBbmXVSKLv3bJQEEEBFUcRX0fJuslR3gCVySEaSh7vuMx5w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.0.10", + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/keccak256": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.0.7.tgz", + "integrity": "sha512-zpUBmofWvx9PGfc7IICobgFQSgNmTOGTGLUxSYqZzY/T+b4y/2o5eqf/GGmD7qnTGzKQ42YlLNo+LeDP2qe55g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "js-sha3": "0.5.7" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/logger": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.8.tgz", + "integrity": "sha512-SkJCTaVTnaZ3/ieLF5pVftxGEFX56pTH+f2Slrpv7cU0TNpUZNib84QQdukd++sWUp/S7j5t5NW+WegbXd4U/A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true + }, + "node_modules/ganache-core/node_modules/@ethersproject/networks": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.7.tgz", + "integrity": "sha512-dI14QATndIcUgcCBL1c5vUr/YsI5cCHLN81rF7PU+yS7Xgp2/Rzbr9+YqpC6NBXHFUASjh6GpKqsVMpufAL0BQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/properties": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.7.tgz", + "integrity": "sha512-812H1Rus2vjw0zbasfDI1GLNPDsoyX1pYqiCgaR1BuyKxUTbwcH1B+214l6VGe1v+F6iEVb7WjIwMjKhb4EUsg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/rlp": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.7.tgz", + "integrity": "sha512-ulUTVEuV7PT4jJTPpfhRHK57tkLEDEY9XSYJtrSNHOqdwMvH0z7BM2AKIMq4LVDlnu4YZASdKrkFGEIO712V9w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/signing-key": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.0.8.tgz", + "integrity": "sha512-YKxQM45eDa6WAD+s3QZPdm1uW1MutzVuyoepdRRVmMJ8qkk7iOiIhUkZwqKLNxKzEJijt/82ycuOREc9WBNAKg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "elliptic": "6.5.3" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/strings": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.8.tgz", + "integrity": "sha512-5IsdXf8tMY8QuHl8vTLnk9ehXDDm6x9FB9S9Og5IA1GYhLe5ZewydXSjlJlsqU2t9HRbfv97OJZV/pX8DVA/Hw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/logger": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/transactions": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.0.9.tgz", + "integrity": "sha512-0Fu1yhdFBkrbMjenEr+39tmDxuHmaw0pe9Jb18XuKoItj7Z3p7+UzdHLr2S/okvHDHYPbZE5gtANDdQ3ZL1nBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/address": "^5.0.9", + "@ethersproject/bignumber": "^5.0.13", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/constants": "^5.0.8", + "@ethersproject/keccak256": "^5.0.7", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/rlp": "^5.0.7", + "@ethersproject/signing-key": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@ethersproject/web": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.12.tgz", + "integrity": "sha512-gVxS5iW0bgidZ76kr7LsTxj4uzN5XpCLzvZrLp8TP+4YgxHfCeetFyQkRPgBEAJdNrexdSBayvyJvzGvOq0O8g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "optional": true, + "dependencies": { + "@ethersproject/base64": "^5.0.7", + "@ethersproject/bytes": "^5.0.9", + "@ethersproject/logger": "^5.0.8", + "@ethersproject/properties": "^5.0.7", + "@ethersproject/strings": "^5.0.8" + } + }, + "node_modules/ganache-core/node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "optional": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@types/node": { + "version": "14.14.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", + "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", + "dev": true + }, + "node_modules/ganache-core/node_modules/@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@types/secp256k1": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz", + "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/abstract-leveldown": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz", + "integrity": "sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "optional": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/aes-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ganache-core/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/ganache-core/node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.11" + } + }, + "node_modules/ganache-core/node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/ganache-core/node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/ganache-core/node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "dependencies": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "dependencies": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "dependencies": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "dependencies": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "dependencies": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "dependencies": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "dependencies": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "dependencies": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/ganache-core/node_modules/babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "dependencies": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "dependencies": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/ganache-core/node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/ganache-core/node_modules/babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ganache-core/node_modules/babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/babelify": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "dev": true, + "dependencies": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true, + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/ganache-core/node_modules/backoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", + "dev": true, + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/ganache-core/node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ganache-core/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/ganache-core/node_modules/bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "dev": true, + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/bip39": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", + "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "node_modules/ganache-core/node_modules/blakejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=", + "dev": true + }, + "node_modules/ganache-core/node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "node_modules/ganache-core/node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "optional": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/ganache-core/node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "optional": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "optional": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "dev": true, + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/ganache-core/node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/ganache-core/node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "node_modules/ganache-core/node_modules/bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/ganache-core/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/bytewise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", + "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=", + "dev": true, + "dependencies": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "node_modules/ganache-core/node_modules/bytewise-core": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", + "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=", + "dev": true, + "dependencies": { + "typewise-core": "^1.2" + } + }, + "node_modules/ganache-core/node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "optional": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/cachedown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz", + "integrity": "sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=", + "dev": true, + "dependencies": { + "abstract-leveldown": "^2.4.1", + "lru-cache": "^3.2.0" + } + }, + "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", + "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/caniuse-lite": { + "version": "1.0.30001174", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001174.tgz", + "integrity": "sha512-tqClL/4ThQq6cfFXH3oJL4rifFBeM6gTkphjao5kgwMaW9yn0tKgQLAEfKzDwj6HQWCB/aWo8kTFlSvIN8geEA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/ganache-core/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/checkpoint-store": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", + "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", + "dev": true, + "dependencies": { + "functional-red-black-tree": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "optional": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-core/node_modules/class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "optional": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ganache-core/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/ganache-core/node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/ganache-core/node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/ganache-core/node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "optional": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "optional": true, + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/ganache-core/node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/ganache-core/node_modules/core-js-pure": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.8.2.tgz", + "integrity": "sha512-v6zfIQqL/pzTVAbZvYUozsxNfxcFb6Ks3ZfEbuneJl3FW9Jb8F6vLWB6f+qTmAu72msUdyb84V8d/yBFf7FNnw==", + "deprecated": "core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/ganache-core/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/ganache-core/node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "optional": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/ganache-core/node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/ganache-core/node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/ganache-core/node_modules/cross-fetch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", + "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==", + "dev": true, + "dependencies": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + } + }, + "node_modules/ganache-core/node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "optional": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/ganache-core/node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "optional": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/deferred-leveldown": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", + "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~5.0.0", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", + "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ganache-core/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "node_modules/ganache-core/node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ganache-core/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "optional": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/dotignore": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", + "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + }, + "bin": { + "ignored": "bin/ignored" + } + }, + "node_modules/ganache-core/node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/electron-to-chromium": { + "version": "1.3.636", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.636.tgz", + "integrity": "sha512-Adcvng33sd3gTjNIDNXGD1G4H6qCImIy2euUJAQHtLNplEKU5WEz5KRJxupRNIIT8sD5oFZLTKBWAf12Bsz24A==", + "dev": true + }, + "node_modules/ganache-core/node_modules/elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/ganache-core/node_modules/encoding-down": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz", + "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==", + "dev": true, + "dependencies": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", + "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/ganache-core/node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/ganache-core/node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/ganache-core/node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/ganache-core/node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz", + "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==", + "dev": true, + "dependencies": { + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", + "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "dev": true, + "optional": true, + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-infura": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz", + "integrity": "sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==", + "dev": true, + "dependencies": { + "cross-fetch": "^2.1.1", + "eth-json-rpc-middleware": "^1.5.0", + "json-rpc-engine": "^3.4.0", + "json-rpc-error": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", + "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==", + "dev": true, + "dependencies": { + "async": "^2.5.0", + "eth-query": "^2.1.2", + "eth-tx-summary": "^3.1.2", + "ethereumjs-block": "^1.6.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.2", + "ethereumjs-vm": "^2.1.0", + "fetch-ponyfill": "^4.0.0", + "json-rpc-engine": "^3.6.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "tape": "^4.6.3" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", + "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", + "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==", + "dev": true, + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", + "deprecated": "New package name format for new versions: @ethereumjs/block. Please update.", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", + "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz", + "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==", + "deprecated": "New package name format for new versions: @ethereumjs/vm. Please update.", + "dev": true, + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz", + "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==", + "deprecated": "New package name format for new versions: @ethereumjs/block. Please update.", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", + "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "dev": true, + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "dev": true, + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "dev": true, + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", + "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", + "dev": true, + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-query": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", + "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", + "dev": true, + "dependencies": { + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.0.tgz", + "integrity": "sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ==", + "deprecated": "Deprecated in favor of '@metamask/eth-sig-util'", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "elliptic": "^6.4.0", + "ethereumjs-abi": "0.6.5", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.0", + "tweetnacl-util": "^0.15.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz", + "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", + "dev": true, + "dependencies": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz", + "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==", + "dev": true, + "dependencies": { + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz", + "integrity": "sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==", + "dev": true, + "dependencies": { + "async": "^2.1.2", + "clone": "^2.0.0", + "concat-stream": "^1.5.1", + "end-of-stream": "^1.1.0", + "eth-query": "^2.0.2", + "ethereumjs-block": "^1.4.1", + "ethereumjs-tx": "^1.1.1", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.6.0", + "through2": "^2.0.3" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", + "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", + "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==", + "dev": true, + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", + "deprecated": "New package name format for new versions: @ethereumjs/block. Please update.", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", + "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz", + "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==", + "deprecated": "New package name format for new versions: @ethereumjs/vm. Please update.", + "dev": true, + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz", + "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==", + "deprecated": "New package name format for new versions: @ethereumjs/block. Please update.", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", + "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "dev": true, + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "dev": true, + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "dev": true, + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", + "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", + "dev": true, + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethashjs": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz", + "integrity": "sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==", + "deprecated": "New package name format for new versions: @ethereumjs/ethash. Please update.", + "dev": true, + "dependencies": { + "async": "^2.1.2", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.0.2", + "miller-rabin": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", + "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.7.tgz", + "integrity": "sha512-vU5rtZBlZsgkTw3o6PDKyB8li2EgLavnAbsKcfsH2YhHH1Le+PP8vEiMnAnvgc1B6uMoaM5GDCrVztBw0Q5K9g==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereum-bloom-filters": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz", + "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==", + "dev": true, + "optional": true, + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/ethereum-common": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", + "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-account": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz", + "integrity": "sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==", + "deprecated": "Please use Util.Account class found on package ethereumjs-util@^7.0.6 https://github.com/ethereumjs/ethereumjs-util/releases/tag/v7.0.6", + "dev": true, + "dependencies": { + "ethereumjs-util": "^6.0.0", + "rlp": "^2.2.1", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz", + "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==", + "deprecated": "New package name format for new versions: @ethereumjs/block. Please update.", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", + "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "dev": true, + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "dev": true, + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "dev": true, + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", + "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", + "dev": true, + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-blockchain": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz", + "integrity": "sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==", + "deprecated": "New package name format for new versions: @ethereumjs/blockchain. Please update.", + "dev": true, + "dependencies": { + "async": "^2.6.1", + "ethashjs": "~0.0.7", + "ethereumjs-block": "~2.2.2", + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.1.0", + "flow-stoplight": "^1.0.0", + "level-mem": "^3.0.1", + "lru-cache": "^5.1.1", + "rlp": "^2.2.2", + "semaphore": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-common": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz", + "integrity": "sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ==", + "deprecated": "New package name format for new versions: @ethereumjs/common. Please update.", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", + "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz", + "integrity": "sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA==", + "deprecated": "New package name format for new versions: @ethereumjs/vm. Please update.", + "dev": true, + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "core-js-pure": "^3.0.1", + "ethereumjs-account": "^3.0.0", + "ethereumjs-block": "^2.2.2", + "ethereumjs-blockchain": "^4.0.3", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.2", + "ethereumjs-util": "^6.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1", + "util.promisify": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", + "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "dev": true, + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "dev": true, + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "dev": true, + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", + "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", + "dev": true, + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ethereumjs-wallet": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz", + "integrity": "sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==", + "dev": true, + "optional": true, + "dependencies": { + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", + "ethereum-cryptography": "^0.1.3", + "ethereumjs-util": "^6.0.0", + "randombytes": "^2.0.6", + "safe-buffer": "^5.1.2", + "scryptsy": "^1.2.1", + "utf8": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "node_modules/ganache-core/node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dev": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ganache-core/node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ganache-core/node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "optional": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/express/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "dependencies": { + "type": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/ext/node_modules/type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", + "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", + "dev": true, + "dependencies": { + "checkpoint-store": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/ganache-core/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", + "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", + "dev": true, + "dependencies": { + "node-fetch": "~1.7.1" + } + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "dev": true, + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz", + "integrity": "sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==", + "dev": true, + "dependencies": { + "fs-extra": "^4.0.3", + "micromatch": "^3.1.4" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/flow-stoplight": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flow-stoplight/-/flow-stoplight-1.0.0.tgz", + "integrity": "sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s=", + "dev": true + }, + "node_modules/ganache-core/node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/ganache-core/node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/ganache-core/node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/ganache-core/node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/ganache-core/node_modules/get-intrinsic": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", + "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "optional": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-core/node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/ganache-core/node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "optional": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ganache-core/node_modules/got/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "optional": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/ganache-core/node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true, + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "optional": true, + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/heap": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", + "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=", + "dev": true + }, + "node_modules/ganache-core/node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "optional": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/ganache-core/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "optional": true, + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ganache-core/node_modules/immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", + "dev": true + }, + "node_modules/ganache-core/node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/ganache-core/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-core/node_modules/is-fn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz", + "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "dev": true, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/ganache-core/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/ganache-core/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "optional": true, + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ganache-core/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/ganache-core/node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/json-rpc-engine": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/json-rpc-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", + "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/json-rpc-random-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz", + "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=", + "dev": true + }, + "node_modules/ganache-core/node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/ganache-core/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/ganache-core/node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/ganache-core/node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/ganache-core/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/ganache-core/node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/ganache-core/node_modules/keccak": { + "version": "3.0.1", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "optional": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/ganache-core/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/ganache-core/node_modules/level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "dev": true, + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "dev": true, + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-iterator-stream": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz", + "integrity": "sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/level-mem": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz", + "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==", + "dev": true, + "dependencies": { + "level-packager": "~4.0.0", + "memdown": "~3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/abstract-leveldown": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", + "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz", + "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~5.0.0", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-mem/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/level-packager": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz", + "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==", + "dev": true, + "dependencies": { + "encoding-down": "~5.0.0", + "levelup": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/level-post": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz", + "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==", + "dev": true, + "dependencies": { + "ltgt": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/level-sublevel": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.4.tgz", + "integrity": "sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==", + "dev": true, + "dependencies": { + "bytewise": "~1.1.0", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "level-iterator-stream": "^2.0.3", + "ltgt": "~2.1.1", + "pull-defer": "^0.2.2", + "pull-level": "^2.0.3", + "pull-stream": "^3.6.8", + "typewiselite": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/level-ws": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz", + "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.8", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/levelup": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz", + "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==", + "dev": true, + "dependencies": { + "deferred-leveldown": "~4.0.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~3.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz", + "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/looper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", + "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=", + "dev": true + }, + "node_modules/ganache-core/node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/ganache-core/node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/ltgt": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", + "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", + "dev": true + }, + "node_modules/ganache-core/node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz", + "integrity": "sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==", + "dev": true, + "dependencies": { + "async": "^2.6.1", + "ethereumjs-util": "^5.2.0", + "level-mem": "^3.0.1", + "level-ws": "^1.0.0", + "readable-stream": "^3.0.6", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/ganache-core/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/mime-db": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/mime-types": { + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "dev": true, + "dependencies": { + "mime-db": "1.45.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/ganache-core/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/ganache-core/node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/ganache-core/node_modules/minizlib/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ganache-core/node_modules/mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", + "dev": true, + "optional": true, + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/mock-fs": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz", + "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "optional": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/ganache-core/node_modules/multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "optional": true, + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "optional": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/ganache-core/node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "node_modules/ganache-core/node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/node-addon-api": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-core/node_modules/node-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", + "dev": true, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/ganache-core/node_modules/node-gyp-build": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache-core/node_modules/normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ganache-core/node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object-is": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz", + "integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ganache-core/node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz", + "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/oboe": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz", + "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=", + "dev": true, + "optional": true, + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "optional": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ganache-core/node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "optional": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/p-timeout/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "optional": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/parse-headers": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", + "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.2.2.tgz", + "integrity": "sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg==", + "dev": true, + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^1.2.1", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "npm": ">5" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/ganache-core/node_modules/patch-package/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/ganache-core/node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/ganache-core/node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-core/node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/ganache-core/node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/ganache-core/node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/ganache-core/node_modules/promise-to-callback": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", + "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", + "dev": true, + "dependencies": { + "is-fn": "^1.0.0", + "set-immediate-shim": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "optional": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ganache-core/node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/ganache-core/node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/ganache-core/node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-core/node_modules/pull-cat": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", + "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=", + "dev": true + }, + "node_modules/ganache-core/node_modules/pull-defer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz", + "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/pull-level": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz", + "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==", + "dev": true, + "dependencies": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "node_modules/ganache-core/node_modules/pull-live": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", + "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=", + "dev": true, + "dependencies": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "node_modules/ganache-core/node_modules/pull-pushable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", + "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=", + "dev": true + }, + "node_modules/ganache-core/node_modules/pull-stream": { + "version": "3.6.14", + "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.14.tgz", + "integrity": "sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==", + "dev": true + }, + "node_modules/ganache-core/node_modules/pull-window": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", + "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=", + "dev": true, + "dependencies": { + "looper": "^2.0.0" + } + }, + "node_modules/ganache-core/node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/ganache-core/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "optional": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-core/node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "optional": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-core/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "optional": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/ganache-core/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/ganache-core/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "node_modules/ganache-core/node_modules/regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "node_modules/ganache-core/node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/regexp.prototype.flags/node_modules/es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/ganache-core/node_modules/regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "node_modules/ganache-core/node_modules/regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/ganache-core/node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/ganache-core/node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-core/node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/ganache-core/node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "optional": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "dev": true, + "dependencies": { + "through": "~2.3.4" + } + }, + "node_modules/ganache-core/node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-core/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-core/node_modules/rlp": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz", + "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.1" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/ganache-core/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ganache-core/node_modules/safe-event-emitter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz", + "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==", + "deprecated": "Renamed to @metamask/safe-event-emitter", + "dev": true, + "dependencies": { + "events": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/ganache-core/node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/ganache-core/node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/scryptsy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", + "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", + "dev": true, + "optional": true, + "dependencies": { + "pbkdf2": "^3.0.3" + } + }, + "node_modules/ganache-core/node_modules/secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-core/node_modules/seedrandom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.1.tgz", + "integrity": "sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==", + "dev": true + }, + "node_modules/ganache-core/node_modules/semaphore": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", + "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ganache-core/node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ganache-core/node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "optional": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ganache-core/node_modules/servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, + "optional": true, + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/ganache-core/node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/ganache-core/node_modules/simple-get": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", + "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "dev": true, + "optional": true, + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ganache-core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/ganache-core/node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/ganache-core/node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/stream-to-pull-stream": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz", + "integrity": "sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==", + "dev": true, + "dependencies": { + "looper": "^3.0.0", + "pull-stream": "^3.2.3" + } + }, + "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", + "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=", + "dev": true + }, + "node_modules/ganache-core/node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ganache-core/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/string.prototype.trim": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.3.tgz", + "integrity": "sha512-16IL9pIBA5asNOSukPfxX2W68BaBvxyiRK16H3RA/lWW9BDosh+w7f+LhomPHpXJ82QEe7w7/rY/S1CV97raLg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "dev": true, + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-core/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", + "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", + "dev": true, + "optional": true, + "dependencies": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "optional": true, + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "optional": true, + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tape": { + "version": "4.13.3", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.13.3.tgz", + "integrity": "sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw==", + "dev": true, + "dependencies": { + "deep-equal": "~1.1.1", + "defined": "~1.0.0", + "dotignore": "~0.1.2", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.6", + "has": "~1.0.3", + "inherits": "~2.0.4", + "is-regex": "~1.0.5", + "minimist": "~1.2.5", + "object-inspect": "~1.7.0", + "resolve": "~1.17.0", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.2.1", + "through": "~2.3.8" + }, + "bin": { + "tape": "bin/tape" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tape/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/ganache-core/node_modules/tar/node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/ganache-core/node_modules/tar/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/ganache-core/node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/ganache-core/node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "dependencies": { + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/to-object-path/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-core/node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ganache-core/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ganache-core/node_modules/trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ganache-core/node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "node_modules/ganache-core/node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "node_modules/ganache-core/node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "node_modules/ganache-core/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "optional": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ganache-core/node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/ganache-core/node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/ganache-core/node_modules/typewise": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", + "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=", + "dev": true, + "dependencies": { + "typewise-core": "^1.2.0" + } + }, + "node_modules/ganache-core/node_modules/typewise-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", + "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/typewiselite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz", + "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ganache-core/node_modules/unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/ganache-core/node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/ganache-core/node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "optional": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-core/node_modules/url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ganache-core/node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-core/node_modules/utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/ganache-core/node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/util.promisify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz", + "integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "for-each": "^0.3.3", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache-core/node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ganache-core/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/ganache-core/node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ganache-core/node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/ganache-core/node_modules/web3": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.11.tgz", + "integrity": "sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "web3-bzz": "1.2.11", + "web3-core": "1.2.11", + "web3-eth": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-shh": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-bzz": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.11.tgz", + "integrity": "sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40", + "underscore": "1.9.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.19.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.12.tgz", + "integrity": "sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-core": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.11.tgz", + "integrity": "sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==", + "dev": true, + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-requestmanager": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-helpers": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz", + "integrity": "sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==", + "dev": true, + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-eth-iban": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-method": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.11.tgz", + "integrity": "sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==", + "dev": true, + "optional": true, + "dependencies": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-promievent": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz", + "integrity": "sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==", + "dev": true, + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-requestmanager": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz", + "integrity": "sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==", + "dev": true, + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "web3-providers-http": "1.2.11", + "web3-providers-ipc": "1.2.11", + "web3-providers-ws": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core-subscriptions": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz", + "integrity": "sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==", + "dev": true, + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": { + "version": "12.19.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.12.tgz", + "integrity": "sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-eth": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.11.tgz", + "integrity": "sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==", + "dev": true, + "optional": true, + "dependencies": { + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-accounts": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-eth-ens": "1.2.11", + "web3-eth-iban": "1.2.11", + "web3-eth-personal": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-abi": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz", + "integrity": "sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==", + "dev": true, + "optional": true, + "dependencies": { + "@ethersproject/abi": "5.0.0-beta.153", + "underscore": "1.9.1", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz", + "integrity": "sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==", + "dev": true, + "optional": true, + "dependencies": { + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-common": "^1.3.2", + "ethereumjs-tx": "^2.1.1", + "scrypt-js": "^3.0.1", + "underscore": "1.9.1", + "uuid": "3.3.2", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-contract": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz", + "integrity": "sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==", + "dev": true, + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-ens": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz", + "integrity": "sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==", + "dev": true, + "optional": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "underscore": "1.9.1", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-promievent": "1.2.11", + "web3-eth-abi": "1.2.11", + "web3-eth-contract": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-iban": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz", + "integrity": "sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-personal": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz", + "integrity": "sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.2.11", + "web3-core-helpers": "1.2.11", + "web3-core-method": "1.2.11", + "web3-net": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.19.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.12.tgz", + "integrity": "sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/web3-net": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.11.tgz", + "integrity": "sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==", + "dev": true, + "optional": true, + "dependencies": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-utils": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz", + "integrity": "sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw==", + "dev": true, + "dependencies": { + "async": "^2.5.0", + "backoff": "^2.5.0", + "clone": "^2.0.0", + "cross-fetch": "^2.1.0", + "eth-block-tracker": "^3.0.0", + "eth-json-rpc-infura": "^3.1.0", + "eth-sig-util": "^1.4.2", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.1.5", + "ethereumjs-vm": "^2.3.4", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "readable-stream": "^2.2.9", + "request": "^2.85.0", + "semaphore": "^1.0.3", + "ws": "^5.1.1", + "xhr": "^2.2.0", + "xtend": "^4.0.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", + "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.6.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", + "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", + "deprecated": "Deprecated in favor of '@metamask/eth-sig-util'", + "dev": true, + "dependencies": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-util": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "git+ssh://git@github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0", + "integrity": "sha512-qs8G5KwnIO/thOQjv1RvR/4oiTsy6IaCsN+ory5dbiqFXz8sd239aWJH0wmsVNPimL5X1KzQheUpi6xAo6FU4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", + "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==", + "dev": true, + "dependencies": { + "ethereumjs-util": "^5.0.0", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", + "deprecated": "New package name format for new versions: @ethereumjs/block. Please update.", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "ethereum-common": "0.2.0", + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", + "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz", + "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==", + "deprecated": "New package name format for new versions: @ethereumjs/vm. Please update.", + "dev": true, + "dependencies": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~2.2.0", + "ethereumjs-common": "^1.1.0", + "ethereumjs-util": "^6.0.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.3.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz", + "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==", + "deprecated": "New package name format for new versions: @ethereumjs/block. Please update.", + "dev": true, + "dependencies": { + "async": "^2.0.1", + "ethereumjs-common": "^1.5.0", + "ethereumjs-tx": "^2.1.1", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", + "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", + "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", + "dev": true, + "dependencies": { + "ethereumjs-common": "^1.5.0", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "dev": true, + "dependencies": { + "errno": "~0.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", + "dev": true, + "dependencies": { + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "dev": true, + "dependencies": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "dependencies": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "dependencies": { + "xtend": "~4.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", + "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", + "dev": true, + "dependencies": { + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", + "level-ws": "0.0.0", + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-http": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.11.tgz", + "integrity": "sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==", + "dev": true, + "optional": true, + "dependencies": { + "web3-core-helpers": "1.2.11", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-ipc": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz", + "integrity": "sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==", + "dev": true, + "optional": true, + "dependencies": { + "oboe": "2.1.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-providers-ws": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz", + "integrity": "sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==", + "dev": true, + "optional": true, + "dependencies": { + "eventemitter3": "4.0.4", + "underscore": "1.9.1", + "web3-core-helpers": "1.2.11", + "websocket": "^1.0.31" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-shh": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.11.tgz", + "integrity": "sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==", + "dev": true, + "optional": true, + "dependencies": { + "web3-core": "1.2.11", + "web3-core-method": "1.2.11", + "web3-core-subscriptions": "1.2.11", + "web3-net": "1.2.11" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-utils": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.11.tgz", + "integrity": "sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "optional": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/ganache-core/node_modules/websocket": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.32.tgz", + "integrity": "sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==", + "dev": true, + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ganache-core/node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ganache-core/node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ganache-core/node_modules/whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", + "dev": true + }, + "node_modules/ganache-core/node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/ganache-core/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "optional": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/ganache-core/node_modules/ws/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, + "node_modules/ganache-core/node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dev": true, + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/ganache-core/node_modules/xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dev": true, + "optional": true, + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/ganache-core/node_modules/xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dev": true, + "optional": true, + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/ganache-core/node_modules/xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "dev": true, + "optional": true, + "dependencies": { + "cookiejar": "^2.1.1" + } + }, + "node_modules/ganache-core/node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/ganache-core/node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true, + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/ganache-core/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "optional": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hardhat": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.13.0.tgz", + "integrity": "sha512-ZlzBOLML1QGlm6JWyVAG8lVTEAoOaVm1in/RU2zoGAnYEoD1Rp4T+ZMvrLNhHaaeS9hfjJ1gJUBfiDr4cx+htQ==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@nomicfoundation/ethereumjs-vm": "^6.0.0", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "abort-controller": "^3.0.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "qs": "^6.7.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", + "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", + "dev": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.24", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat-move": { + "version": "0.0.1", + "resolved": "file:../hardhat-move", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^9.1.0", + "neverthrow": "^4.3.1", + "typescript": "^4.6.3" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/hardhat/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/hardhat/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/hardhat/node_modules/solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "dev": true, + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/hardhat/node_modules/solc/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/header-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", + "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.3" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/highlightjs-solidity": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.5.tgz", + "integrity": "sha512-ReXxQSGQkODMUgHcWzVSnfDCDrL2HshOYgw3OlIYmfHeRzUPkfJTUIp95pK4CmbiNG2eMTOmNLpfCz9Zq7Cwmg==", + "dev": true + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", + "dev": true + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dev": true, + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "dev": true, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-lower-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", + "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", + "dev": true, + "dependencies": { + "lower-case": "^1.1.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", + "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-upper-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", + "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", + "dev": true, + "dependencies": { + "upper-case": "^1.1.0" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/iso-url": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz", + "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json-text-sequence": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", + "integrity": "sha1-py8hfcSvxGKf/1/rME3BvVGi89I=", + "dev": true, + "dependencies": { + "delimit-stream": "0.1.0" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", + "dev": true, + "dependencies": { + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/level-transcoder/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.partition": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.partition/-/lodash.partition-4.6.0.tgz", + "integrity": "sha1-o45GtzRp4EILDaEhLmbUFL42S6Q=", + "dev": true + }, + "node_modules/lodash.sum": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lodash.sum/-/lodash.sum-4.0.2.tgz", + "integrity": "sha1-rZDjl5ZdgD1PH/eqWy0Bl/O0Y3s=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "node_modules/lower-case-first": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", + "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", + "dev": true, + "dependencies": { + "lower-case": "^1.1.2" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "node_modules/mcl-wasm": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", + "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", + "dev": true, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-level": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", + "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", + "dev": true, + "dependencies": { + "abstract-level": "^1.0.0", + "functional-red-black-tree": "^1.0.1", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", + "dev": true, + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dev": true, + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "dev": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mock-fs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", + "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", + "dev": true + }, + "node_modules/module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/nano-base32": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nano-base32/-/nano-base32-1.0.1.tgz", + "integrity": "sha1-ulSMh578+5DaHE2eCX20pGySVe8=", + "dev": true + }, + "node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neverthrow": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/neverthrow/-/neverthrow-4.4.2.tgz", + "integrity": "sha512-QVY0ylzBF71pUdLshRrqtweMgqKnE3R37/T82Z5bhO/z8P9z96PC/5pEl2FmiZSy0p+3lsjKerh6jmTWM5fv2g==", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node_modules/node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node_modules/node-environment-flags/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", + "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "dev": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", + "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.2.tgz", + "integrity": "sha512-g0TrA7SbUggROhDPK8cEu/qpItwH2LSKcNl4tlfBNT54XY+nOsqrs0Q68h1V9b3HOSpIWv15jb1lax2hAggdIg==", + "dev": true + }, + "node_modules/oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", + "dev": true, + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "node_modules/parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", + "dev": true + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", + "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", + "dev": true, + "dependencies": { + "camel-case": "^3.0.0", + "upper-case-first": "^1.1.0" + } + }, + "node_modules/patch-package": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", + "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", + "dev": true, + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "node_modules/path-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", + "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postinstall-postinstall": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", + "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", + "dev": true, + "hasInstallScript": true + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz", + "integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/printj": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz", + "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==", + "dev": true, + "bin": { + "printj": "bin/printj.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.1.tgz", + "integrity": "sha512-ksWccjmXOHU2gJBnH0cK1lSYdvSZ0zLoCMSz/nTGh6hDvCSgcRxDyIcOBD6KNxFz3xhMPm/T267Tbe2JRymKEQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", + "dev": true, + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ripemd160-min": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz", + "integrity": "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/rlp/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/sentence-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", + "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case-first": "^1.1.2" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", + "dev": true, + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sha3": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", + "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", + "dev": true, + "dependencies": { + "buffer": "6.0.3" + } + }, + "node_modules/sha3/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/snake-case": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", + "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/solc": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", + "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", + "dev": true, + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dev": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "dev": true, + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/super-split": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/super-split/-/super-split-1.1.0.tgz", + "integrity": "sha512-I4bA5mgcb6Fw5UJ+EkpzqXfiuvVGS/7MuND+oBxNFmxu3ugLNrdIatzBLfhFRMVMLxgSsRy+TjIktgkF9RFSNQ==", + "dev": true + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/swap-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", + "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1", + "upper-case": "^1.1.1" + } + }, + "node_modules/swarm-js": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", + "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/swarm-js/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swarm-js/node_modules/p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/swarm-js/node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swarm-js/node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/test-value": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", + "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "dev": true, + "dependencies": { + "array-back": "^1.0.3", + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/test-value/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/testrpc": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", + "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", + "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", + "dev": true + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/title-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", + "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.0.3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "node_modules/ts-essentials": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", + "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", + "dev": true + }, + "node_modules/ts-generator": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", + "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", + "dev": true, + "dependencies": { + "@types/mkdirp": "^0.5.2", + "@types/prettier": "^2.1.1", + "@types/resolve": "^0.0.8", + "chalk": "^2.4.1", + "glob": "^7.1.2", + "mkdirp": "^0.5.1", + "prettier": "^2.1.2", + "resolve": "^1.8.1", + "ts-essentials": "^1.0.0" + }, + "bin": { + "ts-generator": "dist/cli/run.js" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typechain": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", + "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", + "dev": true, + "dependencies": { + "command-line-args": "^4.0.7", + "debug": "^4.1.1", + "fs-extra": "^7.0.0", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "ts-essentials": "^6.0.3", + "ts-generator": "^0.1.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + } + }, + "node_modules/typechain/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/typechain/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/typechain/node_modules/ts-essentials": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", + "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", + "dev": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + }, + "node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", + "dev": true + }, + "node_modules/undici": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.21.0.tgz", + "integrity": "sha512-HOjK8l6a57b2ZGXOcUsI5NLfoTrfmbOl90ixJDl0AEFG4wgHNDQxtZy15/ZQp7HhjkpaGlp/eneMgtsu1dIlUA==", + "dev": true, + "dependencies": { + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=12.18" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "node_modules/upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "dev": true, + "dependencies": { + "upper-case": "^1.1.1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", + "dev": true + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/utf-8-validate": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", + "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true + }, + "node_modules/util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/web3": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.1.tgz", + "integrity": "sha512-RKVdyZ5FuVEykj62C1o2tc0teJciSOh61jpVB9yb344dBHO3ZV4XPPP24s/PPqIMXmVFN00g2GD9M/v1SoHO/A==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-bzz": "1.7.1", + "web3-core": "1.7.1", + "web3-eth": "1.7.1", + "web3-eth-personal": "1.7.1", + "web3-net": "1.7.1", + "web3-shh": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-bzz": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.1.tgz", + "integrity": "sha512-sVeUSINx4a4pfdnT+3ahdRdpDPvZDf4ZT/eBF5XtqGWq1mhGTl8XaQAk15zafKVm6Onq28vN8abgB/l+TrG8kA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.20.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", + "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "dev": true + }, + "node_modules/web3-core": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.1.tgz", + "integrity": "sha512-HOyDPj+4cNyeNPwgSeUkhtS0F+Pxc2obcm4oRYPW5ku6jnTO34pjaij0us+zoY3QEusR8FfAKVK1kFPZnS7Dzw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.7.1", + "web3-core-method": "1.7.1", + "web3-core-requestmanager": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", + "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.5.3", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-core-helpers/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.1.tgz", + "integrity": "sha512-383wu5FMcEphBFl5jCjk502JnEg3ugHj7MQrsX7DY76pg5N5/dEzxeEMIJFCN6kr5Iq32NINOG3VuJIyjxpsEg==", + "dev": true, + "dependencies": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.7.1", + "web3-core-promievent": "1.7.1", + "web3-core-subscriptions": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method/node_modules/web3-core-promievent": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", + "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-promievent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", + "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-requestmanager": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.1.tgz", + "integrity": "sha512-/EHVTiMShpZKiq0Jka0Vgguxi3vxq1DAHKxg42miqHdUsz4/cDWay2wGALDR2x3ofDB9kqp7pb66HsvQImQeag==", + "dev": true, + "dependencies": { + "util": "^0.12.0", + "web3-core-helpers": "1.7.1", + "web3-providers-http": "1.7.1", + "web3-providers-ipc": "1.7.1", + "web3-providers-ws": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-requestmanager/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-requestmanager/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.1.tgz", + "integrity": "sha512-NZBsvSe4J+Wt16xCf4KEtBbxA9TOwSVr8KWfUQ0tC2KMdDYdzNswl0Q9P58xaVuNlJ3/BH+uDFZJJ5E61BSA1Q==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", + "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "dev": true + }, + "node_modules/web3-core/node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/web3-core/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.1.tgz", + "integrity": "sha512-Uz3gO4CjTJ+hMyJZAd2eiv2Ur1uurpN7sTMATWKXYR/SgG+SZgncnk/9d8t23hyu4lyi2GiVL1AqVqptpRElxg==", + "dev": true, + "dependencies": { + "web3-core": "1.7.1", + "web3-core-helpers": "1.7.1", + "web3-core-method": "1.7.1", + "web3-core-subscriptions": "1.7.1", + "web3-eth-abi": "1.7.1", + "web3-eth-accounts": "1.7.1", + "web3-eth-contract": "1.7.1", + "web3-eth-ens": "1.7.1", + "web3-eth-iban": "1.7.1", + "web3-eth-personal": "1.7.1", + "web3-net": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", + "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/web3-eth-abi/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.1.tgz", + "integrity": "sha512-3xGQ2bkTQc7LFoqGWxp5cQDrKndlX05s7m0rAFVoyZZODMqrdSGjMPMqmWqHzJRUswNEMc+oelqSnGBubqhguQ==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.5.0", + "@ethereumjs/tx": "^3.3.2", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.7.1", + "web3-core-helpers": "1.7.1", + "web3-core-method": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.1.tgz", + "integrity": "sha512-HpnbkPYkVK3lOyos2SaUjCleKfbF0SP3yjw7l551rAAi5sIz/vwlEzdPWd0IHL7ouxXbO0tDn7jzWBRcD3sTbA==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.7.1", + "web3-core-helpers": "1.7.1", + "web3-core-method": "1.7.1", + "web3-core-promievent": "1.7.1", + "web3-core-subscriptions": "1.7.1", + "web3-eth-abi": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/web3-eth-contract/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-core-promievent": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", + "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-eth-abi": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", + "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.1.tgz", + "integrity": "sha512-DVCF76i9wM93DrPQwLrYiCw/UzxFuofBsuxTVugrnbm0SzucajLLNftp3ITK0c4/lV3x9oo5ER/wD6RRMHQnvw==", + "dev": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.7.1", + "web3-core-helpers": "1.7.1", + "web3-core-promievent": "1.7.1", + "web3-eth-abi": "1.7.1", + "web3-eth-contract": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-core-promievent": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", + "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-eth-abi": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", + "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", + "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.1.tgz", + "integrity": "sha512-02H6nFBNfNmFjMGZL6xcDi0r7tUhxrUP91FTFdoLyR94eIJDadPp4rpXfG7MVES873i1PReh4ep5pSCHbc3+Pg==", + "dev": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.7.1", + "web3-core-helpers": "1.7.1", + "web3-core-method": "1.7.1", + "web3-net": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.20.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", + "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "dev": true + }, + "node_modules/web3-eth-personal/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/web3-eth/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/web3-eth-abi": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", + "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-net": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.1.tgz", + "integrity": "sha512-8yPNp2gvjInWnU7DCoj4pIPNhxzUjrxKlODsyyXF8j0q3Z2VZuQp+c63gL++r2Prg4fS8t141/HcJw4aMu5sVA==", + "dev": true, + "dependencies": { + "web3-core": "1.7.1", + "web3-core-method": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-http": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.1.tgz", + "integrity": "sha512-dmiO6G4dgAa3yv+2VD5TduKNckgfR97VI9YKXVleWdcpBoKXe2jofhdvtafd42fpIoaKiYsErxQNcOC5gI/7Vg==", + "dev": true, + "dependencies": { + "web3-core-helpers": "1.7.1", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-http/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-http/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ipc": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.1.tgz", + "integrity": "sha512-uNgLIFynwnd5M9ZC0lBvRQU5iLtU75hgaPpc7ZYYR+kjSk2jr2BkEAQhFVJ8dlqisrVmmqoAPXOEU0flYZZgNQ==", + "dev": true, + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ipc/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ipc/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.1.tgz", + "integrity": "sha512-Uj0n5hdrh0ESkMnTQBsEUS2u6Unqdc7Pe4Zl+iZFb7Yn9cIGsPJBl7/YOP4137EtD5ueXAv+MKwzcelpVhFiFg==", + "dev": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.1", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ws/node_modules/web3-core-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", + "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "dev": true, + "dependencies": { + "web3-eth-iban": "1.7.1", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ws/node_modules/web3-eth-iban": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", + "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-shh": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.1.tgz", + "integrity": "sha512-NO+jpEjo8kYX6c7GiaAm57Sx93PLYkWYUCWlZmUOW7URdUcux8VVluvTWklGPvdM9H1WfDrol91DjuSW+ykyqg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "web3-core": "1.7.1", + "web3-core-method": "1.7.1", + "web3-core-subscriptions": "1.7.1", + "web3-net": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.1.tgz", + "integrity": "sha512-fef0EsqMGJUgiHPdX+KN9okVWshbIumyJPmR+btnD1HgvoXijKEkuKBv0OmUqjbeqmLKP2/N9EiXKJel5+E1Dw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "node_modules/websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "dev": true, + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", + "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dev": true, + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dev": true, + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dev": true, + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "dev": true, + "dependencies": { + "cookiejar": "^2.1.1" + } + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true, + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/package.json b/vendors/move/crates/evm/hardhat-examples/package.json new file mode 100644 index 000000000..c3a4462e4 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/package.json @@ -0,0 +1,29 @@ +{ + "name": "hardhat-examples", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.5", + "@nomiclabs/hardhat-truffle5": "^2.0.5", + "@nomiclabs/hardhat-waffle": "^2.0.3", + "@nomiclabs/hardhat-web3": "^2.0.0", + "@openzeppelin/test-helpers": "^0.5.15", + "chai": "^4.3.6", + "ethereum-waffle": "^3.4.4", + "ethers": "^5.6.2", + "hardhat": "^2.13.0", + "hardhat-gas-reporter": "^1.0.8", + "hardhat-move": "file:../hardhat-move", + "web3": "^1.7.1" + }, + "dependencies": { + "@openzeppelin/contracts": "^4.5.0" + } +} diff --git a/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC1155.js b/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC1155.js new file mode 100644 index 000000000..987a3c53c --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC1155.js @@ -0,0 +1,23 @@ +async function main() { + const [deployer] = await ethers.getSigners(); + + console.log("Deploying contracts with the account:", deployer.address); + + const weiAmount = (await deployer.getBalance()).toString(); + + console.log("Account balance:", (await ethers.utils.formatEther(weiAmount))); + + const NFT = await ethers.getContractFactory("ERC1155Tradable"); // A Move contract + const nft = await NFT.deploy( + "Move-on-EVM NFT", // name + "MFT", // symbol + "https://bafybeigjlugkiakvejhgfupjdl66e77wlbjznksraj7w2g3djtjdeuhl74.ipfs.nftstorage.link/"); // baseURI + console.log("Semi-NFT address:", nft.address); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC20.js b/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC20.js new file mode 100644 index 000000000..4bafa8ea6 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC20.js @@ -0,0 +1,21 @@ +async function main() { + const [deployer] = await ethers.getSigners(); + + console.log("Deploying contracts with the account:", deployer.address); + + const weiAmount = (await deployer.getBalance()).toString(); + + console.log("Account balance:", (await ethers.utils.formatEther(weiAmount))); + + const Token = await ethers.getContractFactory("ERC20Mock"); // A Move contract + const token = await Token.deploy("MoveOnEvm", "MOE", deployer.address, BigInt(42000 * 10**18)); + + console.log("Token address:", token.address); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC721.js b/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC721.js new file mode 100644 index 000000000..2ee98f343 --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/scripts/deploy_ERC721.js @@ -0,0 +1,26 @@ +async function main() { + const [deployer] = await ethers.getSigners(); + + console.log("Deploying contracts with the account:", deployer.address); + + const weiAmount = (await deployer.getBalance()).toString(); + + console.log("Account balance:", (await ethers.utils.formatEther(weiAmount))); + + const NFT = await ethers.getContractFactory("ERC721Tradable"); // A Move contract + const nft = await NFT.deploy( + "Move-on-EVM on a sunny spring day", // name + "MFT", // symbol + ethers.constants.AddressZero, // proxyRegistryAddress + "https://bafybeifwn437bhus4gjmvvsbnwjiv5of7beujekcaavlkdbwnfw7tewi6u.ipfs.nftstorage.link/" // baseURI + ); + + console.log("NFT address:", nft.address); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/vendors/move/crates/evm/hardhat-examples/scripts/sample-script.js b/vendors/move/crates/evm/hardhat-examples/scripts/sample-script.js new file mode 100644 index 000000000..90cd8197e --- /dev/null +++ b/vendors/move/crates/evm/hardhat-examples/scripts/sample-script.js @@ -0,0 +1,32 @@ +// We require the Hardhat Runtime Environment explicitly here. This is optional +// but useful for running the script in a standalone fashion through `node
+phantom type parameters + +In definitions of both `Coin` and `Balance`, we declare the type parameter `CoinType` +to be phantom because `CoinType` is not used in the struct definition or is only used as a phantom type +parameter. + +Read more about phantom type parameters here. +